gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 02:20:21 25 4
gpt4 key购买 nike

我编写了一个使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com