Eta*_*tan 2 int boolean bit-manipulation type-conversion swift
在 ObjC 中,可以通过将 bool 类型转换为 UInt8 来检索 bool 的位模式。
例如
然后可以将该位模式用于进一步的位操作操作。
现在我想在 Swift 中做同样的事情。
到目前为止我所做的工作是
UInt8(UInt(boolValue))
Run Code Online (Sandbox Code Playgroud)
但这看起来并不是首选方法。
我还需要 O(1) 内的转换,而不需要依赖于数据的分支。所以,像下面这样的东西是不允许的。
boolValue ? 1 : 0
Run Code Online (Sandbox Code Playgroud)
另外,是否有一些关于 UInt8 和 UInt 初始值设定项实现方式的文档?例如,如果从 bool 转换的 UInt 初始值设定项使用数据相关分支,我也无法使用它。
当然,后备方法始终是使用进一步的按位运算来完全避免 bool 值(例如,使用 C 中的按位运算符检查数字是否非零)。
如有疑问,请查看生成的汇编代码:)
func foo(someBool : Bool) -> UInt8 {
let x = UInt8(UInt(someBool))
return x
}
Run Code Online (Sandbox Code Playgroud)
编译(“-O”=“优化编译”)
xcrun -sdk macosx swiftc -emit- assembly -O main.swift
给出
.globl __TF4main3fooFSbVSs5UInt8
.对齐4,0x90
__TF4main3fooFSbVSs5UInt8:
.cfi_startproc
推q%rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
调用 __TFE10FoundationSb19_bridgeToObjectiveCfSbFT_CSo8NSNumber
movq %rax, %rdi
调用 __TFE10FoundationSuCfMSuFCSo8NSNumberSu
movzbl %al、%ecx
cmpq %rcx, %rax
jne LBB0_2
弹出%rbp
请求
函数名称可以用以下命令进行分解
$ xcrun -sdk macosx swift-demangle __TFE10FoundationSb19_bridgeToObjectiveCfSbFT_CSo8NSNumber __TFE10FoundationSuCfMSuFCSo8NSNumberSu _TFE10FoundationSb19_bridgeToObjectiveCfSbFT_CSo8NSNumber ---> ext.Foundation.Swift.Bool._bridgeToObjectiveC (Swift.Bool)() -> ObjectiveC.NSNumber _TFE10FoundationSuCfMSuFCSo8NSNumberSu ---> ext.Foundation.Swift.UInt.init (Swift.UInt.Type)(ObjectiveC.NSNumber) -> Swift.UInt
没有UInt带有Bool参数的初始值设定项。所以智能编译器使用了 Swift 和 Foundation 类型之间的自动转换并生成了一些代码,例如
let x = UInt8(NSNumber(bool: someBool).unsignedLongValue)
Run Code Online (Sandbox Code Playgroud)
两次函数调用可能效率不高。(如果您仅在没有基础的情况下,它不会编译import Swift。)
现在是另一种假设数据相关分支的方法:
func bar(someBool : Bool) -> UInt8 {
let x = UInt8(someBool ? 1 : 0)
return x
}
Run Code Online (Sandbox Code Playgroud)
汇编代码是
.globl __TF4main3barFSbVSs5UInt8
.对齐4,0x90
__TF4main3barFSbVSs5UInt8:
推q%rbp
movq %rsp, %rbp
andb $1, %dil
movb %dil, %al
弹出%rbp
请求
没有分支,只是一个“AND”运算0x01!
因此,我认为没有理由不使用这种“直接”转换。然后,您可以使用 Instruments 进行分析,以检查它是否是您的应用程序的瓶颈。