我很想知道Swift 1.2编译器是否优化了空闭包.以下两个陈述是否相同?
1:
self.presentViewController(alertController, animated: true) {}
Run Code Online (Sandbox Code Playgroud)
2:
self.presentViewController(alertController, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)
谢谢!
正如@rickster建议的那样,我看一下这个文件生成的x86程序集(simple.swift):
func thingWithClosure(a: Int, b: (() -> Void)?) {
println(a)
b?()
}
thingWithClosure(3) {
println("i'm a closure")
}
thingWithClosure(5, nil)
thingWithClosure(2) {}
Run Code Online (Sandbox Code Playgroud)
我的装配非常生疏,但我可以稍微眯一下......
未优化生成的x86程序集的.main部分,或至少部分部分,如下所示:
callq _swift_once
movq __TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__@GOTPCREL(%rip), %rax
movq -64(%rbp), %rcx
movq %rcx, (%rax)
leaq l_metadata+16(%rip), %rdi
movl $32, %r9d
movl %r9d, %eax
movl $7, %r9d
movl %r9d, %edx
movq %rax, %rsi
movq %rdx, -80(%rbp)
movq %rax, -88(%rbp)
callq _swift_allocObject
leaq __TF6simpleU_FT_T_(%rip), %rcx
movq %rcx, 16(%rax)
movq $0, 24(%rax)
leaq __TPA__TTRXFo__dT__XFo_iT__iT__(%rip), %rcx
movq %rcx, -16(%rbp)
movq %rax, -8(%rbp)
movq -16(%rbp), %rsi
movl $3, %r9d
movl %r9d, %edi
movq %rax, %rdx
--> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_
movq $0, -24(%rbp)
movq $0, -32(%rbp)
movl $5, %r9d
movl %r9d, %edi
movq -72(%rbp), %rsi
movq -72(%rbp), %rdx
--> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_
leaq l_metadata2+16(%rip), %rdi
movq -88(%rbp), %rsi
movq -80(%rbp), %rdx
callq _swift_allocObject
leaq __TF6simpleU0_FT_T_(%rip), %rcx
movq %rcx, 16(%rax)
movq $0, 24(%rax)
leaq __TPA__TTRXFo__dT__XFo_iT__iT__3(%rip), %rcx
movq %rcx, -48(%rbp)
movq %rax, -40(%rbp)
movq -48(%rbp), %rsi
movl $2, %r9d
movl %r9d, %edi
movq %rax, %rdx
--> callq __TF6simple16thingWithClosureFTSiGSqFT_T___T_
xorl %eax, %eax
addq $96, %rsp
popq %rbp
retq
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
我已经指出了调用函数的位置-->.从每条callq指令查看一些指令,您可以看到a参数移入r9d寄存器的位置.
同样,优化输出:
callq _swift_once
movq __TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__@GOTPCREL(%rip), %rax
movq %r14, (%rax)
movq $3, -24(%rbp)
movq __TMdSi@GOTPCREL(%rip), %rbx
addq $8, %rbx
leaq -24(%rbp), %rdi
movq %rbx, %rsi
callq __TFSs7printlnU__FQ_T_
leaq L___unnamed_1(%rip), %rax
movq %rax, -48(%rbp)
movq $13, -40(%rbp)
movq $0, -32(%rbp)
movq __TMdSS@GOTPCREL(%rip), %rsi
addq $8, %rsi
leaq -48(%rbp), %rdi
--> callq __TFSs7printlnU__FQ_T_
movq $5, -56(%rbp)
leaq -56(%rbp), %rdi
movq %rbx, %rsi
--> callq __TFSs7printlnU__FQ_T_
movq $2, -64(%rbp)
leaq -64(%rbp), %rdi
movq %rbx, %rsi
--> callq __TFSs7printlnU__FQ_T_
xorl %eax, %eax
addq $48, %rsp
popq %rbx
popq %r14
popq %rbp
retq
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
这里,编译器已经内联了函数,所以我已经指出了println调用-->.
几年前我使用模拟的16位cpu介绍了x86程序集,所以我不会假装我确切地知道这里发生了什么,但在我看来,编译时-O,编译器会发出大致相同的代码(就指令数而言,但可能不是在内存查找等方面).似乎调用println是穿插leaq(加载有效地址)指令,所以我们可以跳到那里,但我不确定在哪里(可能是更多的指令?可能是加载静态数据?),或者如果它事项.
未经优化的版本会针对nil参数案例发出明显更多的指令,因此主要区别可能是调试性能.
当然,这是x86,所以它在ARM上可能完全不同......也许ARM组件,LLVM IR或Swift IR输出会带来更多光线?
如果有更好理解的人可以澄清,我很乐意更新这个答案.
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |