作爲參考,在C/C++中,等效(sizeof
運算符)是編譯時間,可以與模板編程(泛型)一起使用。是MemoryLayout <T> .size/stride/alignment編譯時間?
我一直在尋找通過SWIFT算法俱樂部常見的數據結構的實現,並在其執行位set的傳來:
public struct BitSet {
private(set) public var size: Int
private let N = 64
public typealias Word = UInt64
fileprivate(set) public var words: [Word]
public init(size: Int) {
precondition(size > 0)
self.size = size
// Round up the count to the next multiple of 64.
let n = (size + (N-1))/N
words = [Word](repeating: 0, count: n)
}
<clipped>
是sizeof存在的編譯時間常數操作語言,我會將N
設置爲sizeof(Word) * 8
或者更確切地說MemoryLayout<UInt64>.size * 8
而不是「幻數」64.我承認,它在這裏並不是非常神奇,但是這一點僅僅是爲了使它在語義上清楚發生了什麼。
此外,我注意到了適用於相同問題的函數族(ref)。
static func size(ofValue value: T) -> Int
static func stride(ofValue value: T) -> Int
static func alignment(ofValue value: T) -> Int
編輯:從通用/非通用版本的函數中添加一些反彙編。
非通用快捷:
func getSizeOfInt() -> Int {
return MemoryLayout<UInt64>.size
}
產生以下拆解:
(lldb) disassemble --frame
MemoryLayout`getSizeOfInt() -> Int:
0x1000013c0 <+0>: pushq %rbp
0x1000013c1 <+1>: movq %rsp, %rbp
0x1000013c4 <+4>: movl $0x8, %eax
-> 0x1000013c9 <+9>: popq %rbp
0x1000013ca <+10>: retq
基礎上不斷0x8中,這看起來像基於@Charles Srstka的回答一個編譯時不變。
通用的快速實現如何?
func getSizeOf<T>(_ t:T) -> Int {
return MemoryLayout<T>.size
}
生成此拆卸:
(lldb) disassemble --frame
MemoryLayout`getSizeOf<A> (A) -> Int:
0x100001390 <+0>: pushq %rbp
0x100001391 <+1>: movq %rsp, %rbp
0x100001394 <+4>: subq $0x20, %rsp
0x100001398 <+8>: movq %rsi, -0x8(%rbp)
0x10000139c <+12>: movq %rdi, -0x10(%rbp)
-> 0x1000013a0 <+16>: movq -0x8(%rsi), %rax
0x1000013a4 <+20>: movq 0x88(%rax), %rcx
0x1000013ab <+27>: movq %rcx, -0x18(%rbp)
0x1000013af <+31>: callq *0x20(%rax)
0x1000013b2 <+34>: movq -0x18(%rbp), %rax
0x1000013b6 <+38>: addq $0x20, %rsp
0x1000013ba <+42>: popq %rbp
0x1000013bb <+43>: retq
0x1000013bc <+44>: nopl (%rax)
以上不看編譯的時候......?我還不熟悉mac/lldb上的彙編程序。
嘿謝謝。我的彙編程序通常是生鏽的,我根本沒有玩過lldb。但是,我注意到在代碼的「通用」版本中進行了很多工作,我在答案中添加了這些代碼。 – Josh
順便說一下,上面的通用impl拆卸與-O0和-O3相同。我看到你的新增加 - 你說的話很有道理,很有趣。在C++中,甚至templatized版本的sizeof是在編譯時計算的,因爲它*在編譯時是已知的。這就是C++中模板化函數的重點,您專注於類型T並保留類型安全性。我將更深入地探討爲什麼在這種情況下使用這些寄存器並將您的答案標記爲正確。 – Josh
編輯答案以回答您編輯的問題。 –