我正在开发一个项目,我们遵循正确的代码指南。但最近我偶然发现了一个问题,其解决方案不在我的指南中。
问题很简单。我有两个函数,一个保留局部变量来存储返回值,另一个直接返回值而不存储。这里我添加了示例。
class MockClass {
enum InputEnum {
case testOne
case testTwo
case testThree
}
enum ResultEnum {
case resultOne
case resultTwo
case resultThree
}
func testFunction1(_ param1: InputEnum) -> ResultEnum {
var resultEnum: ResultEnum
switch param1 {
case .testOne: resultEnum = .resultOne
case .testTwo: resultEnum = .resultTwo
case .testThree: resultEnum = .resultThree
}
return resultEnum
}
func testFunction2(_ param1: InputEnum) -> ResultEnum {
switch param1 {
case .testOne: return .resultOne
case .testTwo: return .resultTwo
case .testThree: return .resultThree
}
}
}
let myClass = MockClass()
let start1 = DispatchTime.now()
myClass.testFunction1(.testThree)
myClass.testFunction1(.testOne)
let end1 = DispatchTime.now()
let nanoTime1 = end1.uptimeNanoseconds - start1.uptimeNanoseconds
print(nanoTime1)
let start2 = DispatchTime.now()
myClass.testFunction2(.testThree)
myClass.testFunction2(.testOne)
let end2 = DispatchTime.now()
let nanoTime2 = end2.uptimeNanoseconds - start2.uptimeNanoseconds
print(nanoTime2)
为了确定我应该遵循哪个功能指南,我在
Xcode 14.1 playground
中选择了执行时间作为参数。我已经添加了函数执行时间计算代码。
遗憾的是我无法确定哪个函数的执行时间更少。因为如果我改变执行块的位置,执行时间就会改变。
我本能地遵循
testFunction2
作为指导方针。原因是,在testFunction1
中我有一个额外的赋值操作和一个在testFunction2
中不存在的实例变量。
除了赋值操作和创建实例变量之外,我在
testFunction1
中没有发现任何额外的工作。
至于内存消耗,我假设
testFunction2
占用更少的内存,因为没有实例变量。
我的理解足够吗?
这是过早优化的典型例子。
您正在谈论具有 local 变量的函数与没有局部变量的函数。局部变量在堆栈上创建,并且仅在函数执行期间存在。因为局部变量是堆栈变量,所以它们不再占用任何持久内存。
Swift 编译器非常复杂,打开优化后,它很可能会优化掉局部变量,并且两个版本的目标代码将是相同的。
无论如何,执行时间的任何差异都会非常小,以至于难以察觉。
正如其他人所说,游乐场的执行速度非常慢,并且游乐场的缓慢几乎肯定会掩盖您试图衡量的任何性能差异。
您需要设置一个发布版本,该版本可以运行函数的两个版本数百万次,并测量每个版本所需的时间。
在这种情况下,重要的时间是开发人员时间。如果您编写了难以理解和维护的扭曲的、高度优化的代码,但没有创造对应用程序的消费者有意义的速度改进,那么无论现在还是将来,您都在浪费开发人员的时间。开发商很贵。