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 进行分析,以检查它是否是您的应用程序的瓶颈。