我应该将 let 值从 for 循环中取出以获得更好的性能吗?
Posted
技术标签:
【中文标题】我应该将 let 值从 for 循环中取出以获得更好的性能吗?【英文标题】:Should I put let values out of for loops to get better performance? 【发布时间】:2016-03-20 22:35:08 【问题描述】:例如,如果我有这样的代码
for i in 1 ... 10000
let someValue = 9
...
我应该将 let 值排除在循环之外,以便获得更好的性能还是完全没有必要?
autoreleasepool
let someValue = 9
for i in 1 ... 10000
...
有什么想法吗?
【问题讨论】:
反问:为什么要把它放在循环体中? @vikingosegundo 因为它只需要在那里。这也是我在其他代码中使用 autoreleasepool 的原因,因为我不想在其他范围内使用它。 autoreleasepool 对于范围界定来说是一个相当糟糕的主意。使用方法和隐式创建更小的范围。 它不仅与花费的时间有关。这是冤枉的,如果您始终使用相同的值,则无需每次分配内存。您在每个周期中分配和释放内存,如果您使用比 Int 更大的对象,则需要时间和内存。 【参考方案1】:外面
let a = NSDate()
for i in 1...100
let someValue = a
print("Hello World!")
let b = NSDate()
let c: Double = b.timeIntervalSinceDate(a)
print(c)
let d = NSDate()
let someValue = a
for i in 1...100
print("Hello World!")
let e = NSDate()
let f: Double = e.timeIntervalSinceDate(d)
print(f)
在运行最新版本 OSX 的 MacBook Air 上的操场上 c = 0.092 和 f = 0.022
看来您需要改写问题。如果常量不会发生变异,那么它应该在循环之外。循环用于需要变异的重复代码。外部总是更好,因为内部你必须分配另一个实例 i 次而不是一次。
【讨论】:
你的方法很适合我。但是,我想知道如果代码编译在 .swift 文件中,答案是否相同?由于操场是逐行运行的。 不幸的是,游乐场不是测试这个的最佳场所,但如果您将代码作为源文件添加(到游乐场),甚至创建一个可以调整优化的新项目,您可以获得更多可靠的结果。【参考方案2】:对于可以快速初始化的类型,您可能不需要使用第二个版本,因为这只会带来很小的性能提升。
编译器也可以优化它。尤其是在 structs
和 enums
的情况下,因为它们根本无法变异。虽然使用类你可以改变它的内容,如果编译器不能在编译时检查它是否被改变,它就不能被优化。
总而言之,对于 Int
这样一个简单的案例,您可以使用哪一个,因为假设您在 for循环。
注意:针对不同的作用域,Swift 2 引入了do
:
do
let someValue = 9
for i in 1 ... 10000
...
【讨论】:
我创建了一个新的命令行项目并使用@CodyWeaver 的方法。在 100 万次循环的测试中,性能损失仅为 1/1000。所以我相信任何一种方式都可以。谢谢。 我已经给了你一个赞成票,这使得它从 -1 变为 0。我不知道为什么会有反对票,因为我认为你的答案不应该被反对。 @CodyWeaver OwenZhao 如果与此问题无关,请移步聊天。 @Qbyte 我在哪里可以找到聊天?以上是关于我应该将 let 值从 for 循环中取出以获得更好的性能吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用Spring Security + CAS获得循环重定向,但应该正常工作