Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift, why is "let _ = this" faster then "this != nil"?

So my question is why is let _ = this faster then this != nil?

Example:

This is:

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

Slower than:

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
like image 948
Durdu Avatar asked Aug 01 '17 15:08

Durdu


2 Answers

Following Jonathan's response I checked the actual disassembled instructions. Here is the result: For the code:

let this : Bool? = nil
this != nil

we get:

    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

and for:

let this : Bool? = nil
let _ = this

there is:

    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   

Also, thank you Code Different for pointing to the Optimisation level.

Changing the value from [-Onone] to [-O -whole-module-optimisation] will cause a change for the generated asm in the following way:

The

let this : Bool? = nil
let _ = this

has

    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   

and the

let this : Bool? = nil
this != nil

to

    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   

So the resulted instructions are actually the same and the time to execute them should be pretty close.

like image 91
Durdu Avatar answered Sep 19 '22 23:09

Durdu


I would check out this post. They both result in the same underlying assembly instructions. My guess is that they both take such a small amount of time to compile that the time difference you're noticing could be due to other miscellaneous outliers affecting performance.

like image 24
BlueBear Avatar answered Sep 20 '22 23:09

BlueBear