.net - 在IL中初始化大量数据

标签 .net il

我编写了一个使用 System.Reflection.Emit 生成 IL 的编译器。这适用于代码,但我不知道如何发出我也需要包含的大型初始化表。编译器的重点是生成这些表,并且不可能在运行时计算初始化器。

我试图将初始化数据存储在使用 Ldstr 加载的字符串中,但结果证明这些字符串可以得到的总长度有一个硬性限制。

我还尝试发出分配数组的代码,然后分配初始值设定项(a[0]=const0; a[1]=const1; a[2]=const2, ...)。这有效但似乎减慢了执行速度,即使它只在初始化时完成一次。我猜测 JIT 编译器不太喜欢大量的线性代码。

我想我可以尝试将初始化程序作为资源文件包含在内,尽管我认为解析它不会那么快。理想情况下,我想使用某种方法让我将所有内容存储在一个 dll 中。

请问在.net 中初始化大量数据的“通常”方式是什么?

最佳答案

看看 C# 如何初始化值类型的静态数组。 (这可能只适用于值类型)。
IT 在 - 命名空间中创建一个类,其中 <module>位于,名为 <PrivateImplementationDetails>{GUID_OF_YOUR_ASSEMBLY}
在这个类中,它创建一个结构来使用属性初始化数组:

[StructLayout(LayoutKind.Explicit, Size=SIZE_OF_ARRAY_IN_BYTES, Pack=1)]
private struct __StaticArrayInitTypeSize=SIZE_OF_ARRAY_IN_BYTES
{
}

其中 SIZE_OF_ARRAY_IN_BYTES 是元素的字节数乘以数组的长度。 (例如 int[] foo={0,1,2,3,4,5,6,7,8,9} 将是 Size=40)

在程序集中,它将数组的二进制表示分配给 <PrivateImplementationDetails> 中的内部静态只读字段。 .

最后,它将运行时字段句柄加载到保存数组主体的字段,并调用方法 System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray

不幸的是,关于这种方法的文档很糟糕。看起来您将数组传递给它,然后将句柄传递给一个字段。我的示例静态初始值设定项的 IL 如下所示,希望这会有所帮助:
.method private hidebysig specialname rtspecialname static void .cctor() cil managed
{
    .maxstack 8
    L_0000: ldc.i4.s 0x15
    L_0002: newarr int32
    L_0007: dup 
    L_0008: ldtoken valuetype <PrivateImplementationDetails>{D28836D0-542D-4735-8815-954F79B1D29C}/__StaticArrayInitTypeSize=84 <PrivateImplementationDetails>{D28836D0-542D-4735-8815-954F79B1D29C}::$$method0x6000003-1
    L_000d: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
    L_0012: stsfld int32[] Test.Program::vals
    L_0017: ret 
}

关于.net - 在IL中初始化大量数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20982106/

相关文章:

c# - "Specified cast is not valid"仅适用于 MS 版本的发布版本

.net - 使用 Lucene.NET 索引 .PDF、.XLS、.DOC、.PPT

c# - 停止在 WebAPI 中显示整个堆栈跟踪

.net - 为什么 .Net 4.5 中的内存初始化规则发生了变化?

c# - ReliabilityContract 和 IComparer(或其他注入(inject)代码)

visual-studio - 是否有任何从 Visual Studio 项目中编译 CIL 代码的示例

c# - IL Callvirt 等效?

c# - EF4.4 中每个具体类型 (TPC) 映射的表

c# - .NET/C# 中的 TreeView 双击行为

.net - ElasticSearch .Net Nest问题与配置indexSettings