是否有隐藏的费用硬编码数据作为C#中的代码?

我编写了一个工具,生成一个C#源文件,其中包含处理器密集型计算的结果(预计算结果会使我的应用程序的启动时间大约加快15分钟).它是一个byte []看起来像这样:

public static byte[] precomputedData = new byte[]{
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,
    0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
    0x0F,0x10, .... continue for 8000 more lines....

我想知道,是否存在将代码硬编码到代码而不是将其写入二进制文件的隐藏成本?具体来说,我担心C#可能会在RAM中存储两份数据;一个副本包含构建precomputedData(用于反射目的)的所有指令/代码,另一个副本包含构建precomputedData的实际结果.这准确吗?或者是硬编码或将其存储在二进制文件中之间的选择,纯粹是偏好?

我写了一个小测试程序并查看了IL代码.使用静态字段,将生成一个静态构造函数,用于初始化该字段.对于阵列,Bart de Smet在这篇关于 How C# Array Initialiers Work的博文中有一个非常好的解释.

.method private hidebysig specialname rtspecialname static 
void .cctor () cil managed 
{
    // Method begins at RVA 0x2b50
    // Code size 24 (0x18)
    .maxstack 8

    IL_0000: ldc.i4.s 10
    IL_0002: newarr [mscorlib]System.Int32
    IL_0007: dup
    IL_0008: ldtoken field valuetype
        '<PrivateImplementationDetails>{0BB3CD0B-D585-49BF-8408-2CCB3FA63A32}'/'__StaticArrayInitTypeSize=40'
        '<PrivateImplementationDetails>{0BB3CD0B-D585-49BF-8408-2CCB3FA63A32}'::'$$method0x6000013-1'
    IL_000d: call void
        [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class
        [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
    IL_0012: stsfld int32[] Hgx.Test.Program::myarray
    IL_0017: ret
} // end of method Program::.cctor

< PrivateImplementationDetails> … $$方法字段定义为

.field assembly static valuetype 
    '<PrivateImplementationDetails>{0BB3CD0B-D585-49BF-8408-2CCB3FA63A32}'/'__StaticArrayInitTypeSize=40'
    '$$method0x6000013-1' at I_00002b28

据我所知,根据我之前提到的帖子,这意味着数据直接从PE图像初始化.

这是否是一个好的做法是一个不同的问题.

像你一样硬编码的优点是数据很容易加载,并且很难操纵数据,因为它嵌入在可以签名的文件中.缺点当然是预先计算的数据的任何更改意味着您必须重新编译项目.

我可能会使用二进制文件来存储数据,除非我真的担心有人会恶意更改预先计算的数据.加载仅比将其作为静态字段稍微复杂一些,我将重视更改数据而无需重新编译的能力.

相关文章
相关标签/搜索