2017-08-01 99 views
6

所以我的問題是爲什麼let _ = this然後this != nil在Swift中,爲什麼「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 

慢於:

let this : Bool? = true // 

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

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

      // Time 257045414.0 
      // Time 261933863.0 
      // Time 263465919.0 

回答

10

正在關注Jonathanresponse我檢查了實際的拆卸說明。 下面是結果: 的代碼:

let this : Bool? = nil 
this != nil 

我們得到:

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 

有:

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 

而且,謝謝Code Different指向優化級別

改變從[-Onone]值[-O -whole模塊優化]將導致以下面的方式所生成的ASM的變化:

let this : Bool? = nil 
let _ = this 

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 

所以導致指令實際上是相同的,執行起來應該是相當接近的時間。

+0

有趣。這表明編譯器缺少一個非常重要的優化機會。我會建議提交一個bug [到Swift開源項目](https://bugs.swift.org)。 – rickster

+1

什麼是優化級別? –

+0

[Code Different](https://stackoverflow.com/users/2538939/code-different),我更新了回覆 –

1

我想看看this post。它們都導致相同的底層彙編指令。我的猜測是,他們都需要這麼短的時間才能編譯出來,你注意到的時差可能是由於其他雜項異常值影響了性能。

+0

這不太可能,因爲我使用多個場景多次重複測試。 上面的例子只是一些簡短的代碼示例。 –

+0

謝謝[Jonathan](https://stackoverflow.com/users/1704317/jonathan)提及程序集。 IDK,我的想法是... –

相關問題