大型静态数组正在减慢类加载,需要更好/更快的查找方法

Vis*_*ize 4 c# unicode

我有一个带有几个静态数组的类:

一个带有17,720个元素的int []一个带有17,720个元素
的字符串[]

我注意到当我第一次访问这个类时,初始化几乎需要2秒钟,这会导致访问它的GUI暂停.

具体来说,它是Unicode字符名称的查找.第一个数组是第二个数组的索引.

static readonly int[] NAME_INDEX = {
0x0000, 0x0001, 0x0005, 0x002C, 0x003B, ...

static readonly string[] NAMES = {
"Exclamation Mark", "Digit Three", "Semicolon", "Question Mark", ...

以下代码是如何使用数组(给定字符代码).[注意:此代码不是性能问题]

int nameIndex = Array.BinarySearch<int>(NAME_INDEX, code);
if (nameIndex > 0) { return NAMES[nameIndex]; }

我想我正在寻找关于如何构造数据的其他选项,以便1)快速加载类,2)我可以快速获得给定字符代码的"名称".

我不应该将所有这些数千个元素存储在静态数组中吗?

更新
感谢您的所有建议.我已经测试了一种词典方法,添加所有条目的表现似乎真的很差.

下面是一些代码与Unicode数据来测试阵列VS字典 http://drop.io/fontspace/asset/fontspace-unicodesupport-zip

解决方案更新
我测试了我的原始双数组(比两个字典选项都快),后台线程初始化,这有助于提高性能.

然而,真正令人惊讶的是资源流中的二进制文件的运行情况.这是本主题中讨论的最快的解决方案.谢谢大家的回答!

cmp*_*rer 7

所以有几点意见.二进制搜索只有在您的数组已排序时才会起作用,并且从上面的代码段开始,它看起来不会被排序.

由于您的主要目标是查找特定名称,因此您的代码需要使用哈希表.我建议使用一个字典,它会给你O(1)(平均)查找,没有比只有数组更多的开销.

至于加载时间,我同意Andrey的最佳方法是使用单独的线程.使用您正在使用的数据量时,您将获得一些初始化开销.使用GUI的常规做法是为这些活动使用单独的线程,这样您就不会锁定UI.

  • 从后台线程初始化的字典,在程序启动时启动,而不是在需要时,可能是最好的选择. (4认同)

Ada*_*son 5

第一

A的Dictionary<int, string>性能远远超过你的决斗阵列.暂且不论如何这个数据进入阵列/词典(硬编码与从其他位置读取,就像一个资源文件),这仍然是一个更好,更直观的存储机制

第二

正如其他人所建议的那样,在另一个线程中加载.我会使用辅助函数来帮助你解决这个问题.您可以使用这样的方法:

public class YourClass
{
    private static Dictionary<int, string> characterLookup;
    private static ManualResetEvent lookupCreated;

    static YourClass()
    {
        lookupCreated = new ManualResetEvent(false);

        ThreadPool.QueueUserWorkItem(LoadLookup);
    }

    static void LoadLookup(object garbage)
    {
        // add your pairs by calling characterLookup.Add(...)

        lookupCreated.Set();
    }

    public static string GetDescription(int code)
    {
        if (lookupCreated != null)
        {
            lookupCreated.WaitOne();
            lookupCreated.Close();
            lookupCreated = null;
        }

        string output;

        if(!characterLookup.TryGetValue(code, out output)) output = null;

        return output;
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的代码中,调用GetDescription以将整数转换为相应的字符串.如果UI直到稍后才调用它,那么您应该看到启动时间显着减少.但是为了安全起见,我已经包含了一个ManualResetEvent会导致任何调用GetDescription阻塞,直到字典完全加载为止.