在Swift中,为什么“让_ = this”比“this!= nil”更快?

时间:2017-08-01 15:26:57

标签: ios swift xcode syntactic-sugar

所以我的问题是为什么&string[3]let _ = this更快?

示例:

这是:

this != nil

慢于:

let this : Bool? = true //

let start = DispatchTime.now()
for _ in 0...100000000  {
    guard this != nil else { continue }
}
let end = DispatchTime.now()

let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
let timeInterval = Double(nanoTime)
print("Time \(timeInterval)") 

         // Time 5426559135.0
         // Time 5428084767.0
         // Time 5327325459.0

2 个答案:

答案 0 :(得分:10)

关注Jonathan response我检查了实际的反汇编指令。 结果如下: 对于代码:

    0x100001290 <+0>:  pushq  %rbp
    0x100001291 <+1>:  movq   %rsp, %rbp
    0x100001294 <+4>:  subq   $0x30, %rsp
    0x100001298 <+8>:  leaq   0x2c7259(%rip), %rdx      ; type metadata for Swift.Bool
    0x10000129f <+15>: leaq   0x2b66ca(%rip), %rcx      ; protocol witness table for Swift.Bool : Swift.Equatable in Swift
    0x1000012a6 <+22>: leaq   -0x18(%rbp), %rax
    0x1000012aa <+26>: leaq   -0x8(%rbp), %r8
    0x1000012ae <+30>: movb   $0x2, 0x2f940b(%rip)
    0x1000012b5 <+37>: movb   0x2f9404(%rip), %r9b      ; test2.this : Swift.Optional<Swift.Bool>
    0x1000012bc <+44>: movb   %r9b, -0x8(%rbp)
    0x1000012c0 <+48>: movb   $0x2, -0x10(%rbp)
    0x1000012c4 <+52>: movb   -0x10(%rbp), %r9b
    0x1000012c8 <+56>: movb   %r9b, -0x18(%rbp)
    0x1000012cc <+60>: movl   %edi, -0x1c(%rbp)
    0x1000012cf <+63>: movq   %r8, %rdi
    0x1000012d2 <+66>: movq   %rsi, -0x28(%rbp)
    0x1000012d6 <+70>: movq   %rax, %rsi
    0x1000012d9 <+73>: callq  0x10004df10               ; Swift.!= infix <A where A: Swift.Equatable> (Swift.Optional<A>, Swift.Optional<A>) -> Swift.Bool
    0x1000012de <+78>: xorl   %r10d, %r10d
    0x1000012e1 <+81>: movb   %al, -0x29(%rbp)
    0x1000012e4 <+84>: movl   %r10d, %eax
    0x1000012e7 <+87>: addq   $0x30, %rsp
    0x1000012eb <+91>: popq   %rbp
    0x1000012ec <+92>: retq

我们得到:

let this : Bool? = nil
let _ = this

和for:

    0x1000012d0 <+0>:  pushq  %rbp
    0x1000012d1 <+1>:  movq   %rsp, %rbp
    0x1000012d4 <+4>:  xorl   %eax, %eax
    0x1000012d6 <+6>:  movb   $0x2, 0x2f93e3(%rip)
    0x1000012dd <+13>: movl   %edi, -0x4(%rbp)
    0x1000012e0 <+16>: movq   %rsi, -0x10(%rbp)
    0x1000012e4 <+20>: popq   %rbp
    0x1000012e5 <+21>: retq   

有:

let this : Bool? = nil
let _ = this

另外,感谢您Code Different指向优化级别

将值从 [ - Onone] 更改为 [ - O -whole-module-optimization] 将导致生成的asm按以下方式更改:< / p>

    0x100001490 <+0>:  pushq  %rbp
    0x100001491 <+1>:  movq   %rsp, %rbp
    0x100001494 <+4>:  movb   $0x2, 0x3d9595(%rip)      ; gCRAnnotations + 63
    0x10000149b <+11>: xorl   %eax, %eax
    0x10000149d <+13>: popq   %rbp
    0x10000149e <+14>: retq   

let this : Bool? = nil
this != nil

    0x100001490 <+0>:  pushq  %rbp
    0x100001491 <+1>:  movq   %rsp, %rbp
    0x100001494 <+4>:  movb   $0x2, 0x3d9595(%rip)      ; gCRAnnotations + 63
    0x10000149b <+11>: xorl   %eax, %eax
    0x10000149d <+13>: popq   %rbp
    0x10000149e <+14>: retq   

{{1}}

所以结果指令实际上是相同的,执行它们的时间应该非常接近。

答案 1 :(得分:1)

我会查看this post。它们都会产生相同的底层汇编指令。我的猜测是,他们都花了这么短的时间来编译,你注意到的时差可能是由于影响性能的其他异常异常值所致。