在展开swift可选类型时,性能命中(如果有的话)是什么?

时间:2015-02-16 22:09:02

标签: swift

如果我有var x: CustomType?,那么在使用展开x!时会有什么效果? 写作有以下意思:

if let x1 = x {
    f(x1)
    f2(x1)
} 

或者我写的性能相同:

f(x!)
f2(x!)

注意:我知道在第一种情况下检查选项是否有效,但如果我知道此选项在此代码中100%有效,该怎么办?

3 个答案:

答案 0 :(得分:6)

除非你正在编译-Ounchecked(和不要),否则它们最终会非常相似,因为运行时仍会检查可选项是否包含值方式(因为如果你强制 - 解包一个nil值,你得到一个运行时断言,它不仅仅访问内存,就好像它不是nil)。可能会给if let带来优势的是你正在告诉编译器更多关于你要做什么的事情,这使它有更好的机会来优化它。

然而,不要担心这一点,不要费心思考哪个更快,更重要的是,你总是花时间来推断使用!是否安全,因为你的变量肯定几乎可以肯定不会是零(除了那次之外的哎呀),并且更好地使用它。

而是将时间用于优化实际重要的事情。当您在O(n^2)中执行此操作时,请在O(n log n)中查找您正在执行的操作。考虑缓存局部性。考虑在运行时在编译时执行更多操作。不要担心可能会花费你一个CPU指令的东西而不是更安全的替代品。

答案 1 :(得分:1)

我使用Swift 1.2中的以下计算进行了快速基准研究:

var x: Int?
x = 0
var startTime: Double = 0

var benchmark1: Double = 0;
var benchmark2: Double = 0;


for var i = 0; i < 1000; ++i {
    startTime = CFAbsoluteTimeGetCurrent()
    if let y = x {
        let z = y + y
        println(z)
        benchmark1 += CFAbsoluteTimeGetCurrent() - startTime
    }
}

for var i = 0; i < 1000; ++i {
    startTime = CFAbsoluteTimeGetCurrent()
    let y = x!
    let z = y + y
    println(z)
    benchmark2 += CFAbsoluteTimeGetCurrent() - startTime
}

println(benchmark1 / 1000)
println(benchmark2 / 1000)

我的结果一致是if let y = x变体大约需要0.00056秒,而let y = x!变体需要大约0.00059秒。因此,使用let展开您的选项似乎要快一点。

我有兴趣知道这是否在任何地方正式备份,或者是否有其他快速用户获得相同的结果。

答案 2 :(得分:0)

我有一个问题:

使用(Double)与(Double?)使用起来更快吗?

与官方问题相比,这是更糟糕的情况,因为这不是关于let vs force unwrap,而是关于使用数字类型与可选数字类型。我预计会有很大的不同,但是:

实测差异:〜5%

这与其他答案类似。 Swift非常有效地优化了可选开销。