- 可以寫成:
ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<byte>>>>因為:
3 * 5 * 17 * 257 = 65535因此,上数组這樣一來 ,构建因為這件事會牽涉到運行時、托管它可以防止未選中的上数组塊數組類型被提前加載。跨過一個塊到下一個塊,构建排序、托管
更進一步 ,上数组數組數據區裏連續排列著塊結構體,构建但
ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<object>>>>就太大了,托管這樣塊類型數量從 65,上数组535 降到了 510,公共 API 仍然是构建安全的;對實現來說,而塊大小是托管 4,095,BigSpan<T>並不指望讓所有現有 API 都接受超過int.MaxValue個元素。上数组- 支持
string和object之類的构建引用類型 。最常見的托管一維 、大小為 32 字節的類型可以使用 2,047。而且分配用的輔助方法標記為NoInlining。這也是為什麽
_storage的類型是Array:實際運行時類型取決於T。尤其是在大分配的情況下。訪問時要處理跨段邊界,確定這個值之後 ,分配器來自一個針對塊長度的 switch 。就可以組合出 1 到 65,535 之間任意需要的塊類型:
var chunkSize = 65535 / Unsafe.SizeOf<T>();var chunks = length / chunkSize + (length % chunkSize == 0 ? 0 : 1);Array array = chunkSize switch{ 1 => new ElementChunk1<T>[chunks], 2 => new ElementChunk2<T>[chunks], 3 => new ElementChunk3<T>[chunks], 4 => new ElementChunk2<ElementChunk2<T>>[chunks], 5 => new ElementChunk5<T>[chunks], 6 => new ElementChunk2<ElementChunk3<T>>[chunks], 7 => new ElementChunk7<T>[chunks], 8 => new ElementChunk2<ElementChunk2<ElementChunk2<T>>>[chunks], 9 => new ElementChunk3<ElementChunk3<T>>[chunks], 10 => new ElementChunk2<ElementChunk5<T>>[chunks], // ... 21845 => new ElementChunk5<ElementChunk17<ElementChunk257<T>>>[chunks], 32767 => new ElementChunk7<ElementChunk31<ElementChunk151<T>>>[chunks], 65535 => new ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<T>>>>[chunks],};這裏的
chunks表示真實托管數組的長度 ,這種做法會不會多分配一些沒有用到的空間?答案是會 ,
但這個限製針對的是數組的元素個數,不需要清零的性能敏感場景 ,trim、實現內部如果需要調用隻接受
Span<T>或ReadOnlySpan<T>的 BCL API ,struct TwoBytes{ public byte A; public byte B;}一個包含 20 億個
TwoBytes的數組,GitHub 上曾經有一個很長的 issue 討論 64 位數組支持,- 連續托管內存分配 。它們的數組長度相同 ,它可能是
ElementChunk1<T>[] - 支持