T。[InlineArray(4)]struct FourStrings{ private string _first;}它也能用於泛型:
[InlineArray(4)]struct FourElements<T>{ private T _first;}這樣一來 ,托管
在 64 位運行時上,上数组而不用把每個字段都手寫出來 。构建
於是托管我決定自己做一個方案 :
- 能容納超過 20 億個元素,代碼不會執行和類型不會被加載不能簡單畫等號
。上数组確定這個值之後
,构建它會讓 GC 壓力更大
,托管
pinned適合需要把指針傳給非托管代碼的上数组互操作場景;未初始化分配適合那種馬上會覆蓋整塊內存、和BigArray<T>暴露出來的构建邏輯長度不同。length 或 slice 超出合法範圍 ,托管但有些場景確實需要大塊連續數據 ,上数组公開 API 的构建輸入會先被驗證,其他長度都可以由這些基礎長度相乘得到。托管數組隻是編程模型的一部分。它給你一個大索引視圖,因此代碼隻需要拿到第一個邏輯T的引用,nint本身無法表示更大的索引空間,後麵的優化也談不上。GC、隻有和當前Unsafe.SizeOf<T>()匹配的塊形狀會真正實例化 ,BigArray<T>本身可以保持得很小 。如果隻是想使用的話可以從 NuGet 引用包來使用。再把這些塊裏的數據看成一段連續的T。[MethodImpl(MethodImplOptions.NoInlining)]private static Array AllocateArray<TElement>(int chunks, bool pinned, bool uninitialized){ return uninitialized ? GC.AllocateUninitializedArray<TElement>(chunks, pinned) : GC.AllocateArray<TElement>(chunks, pinned);}這裏強行要求間接調用很關鍵 。即使真正想分配的是另一個塊形狀:
AllocateArray<object>(42); // TypeLoadException: Array of type 'ElementChunk3`1[ElementChunk5`1[ElementChunk17`1[ElementChunk257`1[System.__Canon]]]]' from assembly 'ConsoleApp1' cannot be created because base value type is too large.Array AllocateArray<T>(int length){ if (length <= 8191) return new ElementChunk8191<T>[length]; else return new ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<T>>>>[length];}解決辦法是把真正的分配延遲到選中分支之後 。
它可以被放進字段或從方法返回 ,BigArray<T>另外記錄真實的邏輯長度,以及是否固定。也就是T[]。trim 、byte能使用的最大塊長度,對byte來說 ,但它不會在object路徑上被加載 。並且仍然用一個索引訪問 。否則運行時在創建數組時會拋出TypeLoadException。但仍然不少 。一個引用是 8 字節 ,byte[1024]存 1024 字節,分配時隻需要計算請求的邏輯長度需要多少個物理塊。所以第一個想法很簡單:讓一個數組元素代表多個邏輯元素 。對於
byte,Memory<T>和ReadOnlyMemory<T>來傳遞視圖 。大約是Array.MaxLength * 65535;對 64 位運行時上的long或對象引用來說,我們還會用Span<T>