C#和C ++静态数组中静态常量列表初始化的效率

时间:2018-10-21 07:26:23

标签: c# arrays .net performance arraylist

我事先表示歉意。我的领域主要是C(和C ++)。我正在尝试用C#编写类似的内容。让我用代码解释。

在C ++中,我可以使用大型静态数组,这些静态数组在编译时进行处理并存储在PE文件的只读部分中。例如:

typedef struct _MY_ASSOC{
    const char* name;
    unsigned int value;
}MY_ASSOC, *LPMY_ASSOC;

bool GetValueForName(const char* pName, unsigned int* pnOutValue = nullptr)
{
    bool bResult = false;
    unsigned int nValue = 0;

    static const MY_ASSOC all_assoc[] = {
        {"name1", 123},
        {"name2", 213},
        {"name3", 1433},
        //... more to follow
        {"nameN", 12837},
    };

    for(size_t i = 0; i < _countof(all_assoc); i++)
    {
        if(strcmp(all_assoc[i].name, pName) == 0)
        {
            nValue = all_assoc[i].value;
            bResult = true;
            break;
        }
    }

    if(pnOutValue)
        *pnOutValue = nValue;

    return bResult;
}

在上面的示例中,static const MY_ASSOC all_assoc的初始化在运行时从未调用。它是在编译时完全处理的。

现在,如果我用C#编写类似的内容:

    public struct NameValue
    {
        public string name;
        public uint value;
    }

    private static readonly NameValue[] g_arrNV_Assoc = new NameValue[] {
        new NameValue() { name = "name1", value = 123 },
        new NameValue() { name = "name2", value = 213 },
        new NameValue() { name = "name3", value = 1433 },
        // ... more to follow
        new NameValue() { name = "nameN", value = 12837 },
    };

    public static bool GetValueForName(string name, out uint nOutValue)
    {
        foreach (NameValue nv in g_arrNV_Assoc)
        {
            if (name == nv.name)
            {
                nOutValue = nv.value;
                return true;
            }
        }

        nOutValue = 0;
        return false;
    }

private static readonly NameValue[] g_arrNV_Assoc行在主机类初始化期间必须被调用一次,并且必须为该数组中的每个元素完成一次!

我的问题-我可以以某种方式对其进行优化,以便将存储在g_arrNV_Assoc数组中的数据存储在PE部分中,而不在运行时初始化吗?

PS。我希望我对自己的术语了解.NET。

1 个答案:

答案 0 :(得分:1)

实际上,术语足够,大型静态数组就可以了。

您没有真正能做的事情来使它更有效。

它最初将加载一次(在不同时间加载,具体取决于.net的版本以及是否具有静态构造函数)。但是,它将在调用之前加载。

即使您以预定的大小将其创建为空,CLR仍将每个元素初始化为默认值,然后您仍必须以某种方式缓冲数据上的副本,这又将不得不从文件中加载。

问题是

  • 与在C语言中执行的操作相比,加载默认的struct静态数组实际上实际消耗了多少开销
  • 在应用程序的生命周期中加载它有关系

如果这是太多的开销(我已经假设您已经确定),那么框外还有哪些其他选项可用?

您可以预先分配一块非托管内存,然后从某个位置读取和复制字节,然后使用指针进行访问。

您还可以像其他不受管理的DLL一样,在标准的Dll Pinvoke中创建此文件。但是我真的不太确定您是否会在这里得到很多免费午餐,因为要整理这些调用来加载您的dll会有开销。

如果您的问题只是学术性的,那么实际上这是您唯一的选择。但是,如果这实际上是您遇到的性能问题,则需要尝试对其进行基准测试以进行微优化,然后尝试找出适合您的条件。

无论如何,我不承认所有知识,也许其他人有更好的主意或更多信息。祝你好运