展开swift可选类型时,性能影响(如果有)是什么?

展开swift可选类型时,性能影响(如果有)是什么?,swift,Swift,如果我有var x:CustomType?,那么使用展开x时性能会受到什么影响? 写以下内容是否有意义: if let x1 = x { f(x1) f2(x1) } 或者以同样的表现,我可以写: f(x!) f2(x!) 注:我知道在第一种情况下,会检查可选项是否有效,但如果我知道此可选项在此代码中100%有效,该怎么办?我使用Swift 1.2中的以下计算进行了快速基准研究: var x: Int? x = 0 var startTime: Double = 0 va

如果我有
var x:CustomType?
,那么使用展开
x时性能会受到什么影响?
写以下内容是否有意义:

if let x1 = x {
    f(x1)
    f2(x1)
} 
或者以同样的表现,我可以写:

f(x!)
f2(x!)

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

我使用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)
var x:Int?
x=0
var startTime:Double=0
var基准1:Double=0;
var基准2:Double=0;
对于var i=0;i<1000++我{
startTime=CFAbsoluteTimeGetCurrent()
如果让y=x{
设z=y+y
println(z)
benchmark1+=CFAbsoluteTimeGetCurrent()-startTime
}
}
对于var i=0;i<1000++我{
startTime=CFAbsoluteTimeGetCurrent()
让y=x!
设z=y+y
println(z)
benchmark2+=CFAbsoluteTimeGetCurrent()-startTime
}
println(基准1/1000)
println(基准2/1000)
我的结果始终是
if let y=x
变量大约需要0.00056秒,而
let y=x变量大约需要0.00059秒。因此,使用
let
展开选项看起来要快一点


我想知道这是否在任何地方进行了正式备份,或者其他swift用户是否得到了相同的结果。

除非您正在编译
-Ounchecked
(并且没有),否则它们最终将非常相似,因为运行时仍将检查可选项是否以任何方式包含值(因为如果你强制展开一个nil值,你会得到一个运行时断言,它不会像访问非nil的内存一样访问内存)。如果让
去做,可能会给
一个优势,那就是你会告诉编译器更多关于你要做的事情,这会给它一个更好的优化机会

然而,与其担心这一点,不如全神贯注地想一想哪一个更快,更重要的是,你花了所有的时间来思考使用
是否安全,因为你的变量肯定几乎肯定不会是零(除了那一次之外,还有一次),并更好地使用它

相反,把时间花在优化真正重要的东西上。在
O(n^2)
中寻找你在哪里做事情,什么时候你可以在
O(n log n)中做这些事情
。考虑缓存的局部性。考虑在编译时比运行时做更多的事情。不要为可能比更安全的替代方案更耗费一条CPU指令的事情大惊小怪。

我有一个问题:

使用(双倍)比使用(双倍)快吗

这是一个比官方问题更糟糕的情况,因为它不是关于“让”与“强制展开”,而是关于使用数字类型与可选数字类型。然而,我预期会有显著的不同:

测量的差异:~5%


这与另一个答案类似。Swift非常有效地优化了可选的开销。

如果两个基准中都没有使用let x=x
y
,则应该使用,因此两个基准的中心部分可能都得到了优化,给您留下了一个基准,它只需要乘以
CFAbsoluteTimeGetCurrent
此外,13%的壁时间变化可能在误差范围内,因为您的机器上可能会发生其他事情。但实际上,请注意@AirspeedVelocity答案的尾部:或者不要担心这些事情(至少在您看到它对真实世界的性能产生有意义的影响之前)或者确保你根本没有在一个关键的部分处理选项。记住Knuth所说的关于过早优化的话……原则上我同意,并且不会在编写代码时考虑到这些差异,但问题的一部分也是是否存在差异,这似乎也应该得到一个答案。我补充了一点对代码的计算,它仍然产生了相同的一致性。00003种不同。因此,我们有5%种不同的响应和建议,我很欣赏这些,但是作为一个C++开发人员,我想在这个领域里熟悉所有的细节,这只是一种习惯……我认为这是一个很好的习惯。在优化这一点之前,你必须考虑一下——我同意你的看法,但我只想知道引擎盖下面发生了什么。