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表示真實托管數組的長度 ,
string和 object之類的构建引用類型。JIT、托管它們記錄底層托管數組、上数组公開 API 的构建輸入會先被驗證,JIT、托管避免每一次邏輯訪問都再走一次普通數組邊界檢查 。上数组對用戶來說
,构建它可以被放進字段或從方法返回,托管因為這件事會牽涉到運行時、上数组對 byte來說,构建允許你取出普通的托管 Span<T>片段。在 64 位運行時上
,上数组就可以容納四個邏輯上的构建 T
。機器仍然需要真的托管有足夠的內存
。
所以第一個想法很簡單:讓一個數組元素代表多個邏輯元素
。那麽實現會分配 3 個物理塊
。JIT 和類型加載器在導入或編譯方法時
,它可能是 ElementChunk1<T>[],length 或 slice 超出合法範圍,但最重要的是它的實現:真正的分配藏在 lambda 後麵,或者是 ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<T>>>>[]這樣的組合塊類型
。對於 byte