2017-08-01 20 views
6

Vì vậy, câu hỏi của tôi là tại sao là let _ = this nhanh hơn sau đó this != nil?Trong Swift, tại sao "let _ = this" nhanh hơn "this! = Nil"?

Ví dụ:

này là:

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 

chậm hơn:

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 

Trả lời

10

Sau Jonathan 's response Tôi đã kiểm tra hướng dẫn được tháo rời thực tế. Dưới đây là kết quả: Đối với các mã:

let this : Bool? = nil 
this != nil 

chúng tôi nhận được:

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 

và cho:

let this : Bool? = nil 
let _ = this 

có:

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 

Ngoài ra, cảm ơn bạn Code Different để trỏ đến Cấp độ tối ưu hóa.

Thay đổi giá trị từ [-Onone] để [-O -whole-module-tối ưu hóa] sẽ gây ra một sự thay đổi cho asm tạo ra theo cách sau:

Các

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 

Vì vậy, các hướng dẫn kết quả thực sự giống nhau và thời gian để thực hiện chúng nên được khá chặt chẽ.

+0

Thú vị. Và nó cho thấy rằng trình biên dịch thiếu một cơ hội tối ưu hóa khá quan trọng. Tôi muốn đề nghị nộp một lỗi [cho dự án mã nguồn mở Swift] (https://bugs.swift.org). – rickster

+1

Cấp độ tối ưu hóa là gì? –

+0

[Mã khác] (https://stackoverflow.com/users/2538939/code-different), tôi đã cập nhật câu trả lời –

1

tôi sẽ kiểm tra this post. Cả hai kết quả trong cùng một hướng dẫn lắp ráp cơ bản. Tôi đoán là cả hai đều mất một lượng thời gian nhỏ để biên dịch rằng chênh lệch thời gian bạn nhận thấy có thể là do các ngoại lệ khác ảnh hưởng đến hiệu suất.

+0

Điều này không chắc vì tôi đã lặp lại phép thử nhiều lần bằng nhiều tình huống. Các ví dụ trên chỉ là một số mẫu mã ngắn. –

+0

Cảm ơn bạn [Jonathan] (https://stackoverflow.com/users/1704317/jonathan) để đề cập đến lắp ráp. IDK nơi mà tâm trí của tôi là ... –