참조를 위해 C/C++에서 이에 해당하는 (sizeof
연산자) 컴파일 타임이며 템플릿 프로그래밍 (Generics)과 함께 사용할 수 있습니다.MemoryLayout입니까. <T> .size/stride/alignment 컴파일 타임입니까?
나는 일반적인 데이터 구조의 구현을위한 신속한 알고리즘 클럽을 통해보고하고, 비트 세트의 구현 건너 온되었습니다는 sizeof는 컴파일 시간 상수 연산자로 존재하는 언어에서
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>
, 내가 가진 것 N
을 sizeof(Word) * 8
으로 설정하거나 "magic number"64보다는 MemoryLayout<UInt64>.size * 8
으로 설정하십시오. 나는 그다지 마법 같은 것이 아니라는 것을 인정하지만, 그 의미가 무엇인지 의미 론적으로 명확히하기위한 것일뿐입니다.
또한 동일한 질문이 적용되는 함수 계열에 대해 언급했습니다 (ref).
static func size(ofValue value: T) -> Int
static func stride(ofValue value: T) -> Int
static func alignment(ofValue value: T) -> Int
편집 : 일반/일반 버전의 기능에서 일부 디스 어셈블리를 추가합니다.
비 일반 SWIFT는 다음 0x8이 상수를 기반으로
(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
,이 @Charles Srstka의 대답에 따라 컴파일 시간 일정과 같습니다
func getSizeOfInt() -> Int {
return MemoryLayout<UInt64>.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)
시간을 컴파일 보이지 않는 ... :
func getSizeOf<T>(_ t:T) -> Int {
return MemoryLayout<T>.size
}
이 분해를 생산? 아직 mac/lldb에서 어셈블러에 익숙하지 않습니다.
안녕하세요. 내 어셈블러는 일반적으로 녹슬었고 나는 lldb를 전혀 사용하지 않았다. 그러나 나는이 코드의 "일반"버전에서 더 많은 작업을 수행하는 것으로 보았습니다.이 코드를 제 답변에 추가했습니다. – Josh
Btw, 위의 일반적인 impl 디 어셈블리는 -O0과 -O3에서 동일합니다. 나는 당신의 새로운 추가를 본다 - 당신이 말하는 것이 의미 있고 흥미 롭다. C++에서 sizeof의 템플릿 화 된 버전조차도 컴파일 타임에 계산되므로 * 컴파일 타임에 계산되므로 * 계산됩니다. C++에서 템플리트 된 함수의 요점은 T 유형을 전문으로하고 유형 안전성을 유지한다는 것입니다. 나는 왜이 레지스터들이이 경우에 사용되는지에 대해 자세히 살펴보고 답을 정확하게 표시 할 것입니다. – Josh
편집 한 질문에 대한 답변을 편집했습니다. –