最快的数组初始化方法?

4
在我的一个应用程序中,我需要一个大的常量(实际上是static readonly)对象数组。该数组在类型的静态构造函数中进行初始化。
该数组包含一千多个项目,当该类型首次使用时,我的程序会遇到严重的减速。我想知道是否有一种快速初始化大型数组的方法在C#中。
public static class XSampa {
    public class XSampaPair : IComparable<XSampaPair> {
        public XSampaPair GetReverse() {
            return new XSampaPair(Key, Target);
        }
        public string Key { get; private set; }
        public string Target { get; private set; }
        internal XSampaPair(string key, string target) {
            Key = key;
            Target = target;
        }
        public int CompareTo(XSampaPair other) {
            if (other == null)
                throw new ArgumentNullException("other", 
                        "Cannot compare with Null.");
            if (Key == null)
                throw new NullReferenceException("Key is null!");
            if (other.Key == null)
                throw new NullReferenceException("Key is null!");
            if (Key.Length == other.Key.Length)
                return string.Compare(Key, other.Key, 
                        StringComparison.InvariantCulture);
            return other.Key.Length - other.Key;
        }
    }    
    private static readonly XSampaPair[] pairs, reversedPairs;
    public static string ParseXSampaToIpa(this string xsampa) {
        // Parsing code here...
    }
    public static string ParseIpaToXSampa(this string ipa) {
        // reverse code here...
    }
    static XSampa() {
        pairs = new [] {
            new XSampaPair("a", "\u0061"), 
            new XSampaPair("b", "\u0062"),
            new XSampaPair("b_<", "\u0253"), 
            new XSampaPair("c", "\u0063"),
            // And many more pairs initialized here...
        };
        var temp = pairs.Select(x => x.GetReversed());
        reversedPairs = temp.ToArray();
        Array.Sort(pairs);
        Array.Sort(reversedPairs);
    }
}

提示:我使用数组将X-SAMPA音标转换为相应的IPA字符的Unicode字符串。


2
能否使用 IEnumerable<yourobj>,以便在需要时惰性地 yield return 数组? - jb.
1
@jb的解决方案很好,但如果您不想更改任何代码,可以在应用程序启动时(例如闪屏界面)进行初始化。 - user915331
抱歉,您编辑后我才看到,请忽略它。 - Liam McInroy
不能有闪屏,所有内容必须能够在服务器端运行。 - Minustar
2个回答

2
你可以将完全初始化好的对象序列化成二进制文件,将该文件作为资源添加,并在启动时将其加载到数组中。如果你的构造函数很耗费CPU资源,那么你可能会得到一些改进。由于你的代码似乎执行某种解析操作,所以在那里获得合理的改进机会相当高。

能否直接将二进制资源映射到某个内存中,并使pairs指向该内存,就像C++一样? - Minustar
1
只有使用可位移值类型并且只在非托管代码中才能实现此类操作。您不会将资源映射到内存中-您只需从资源流加载即可,但通常速度非常快。然而,这样做的后果是您最终会得到内存中的值类型,这需要特别小心以避免复制。 - Sergey Kalinichenko
这是否与架构无关(x64 vs. x86)和框架版本无关(.net 3 vs .net 2)?序列化不是我的强项。 - Minustar
@Minustar 由于您将反序列化代码与序列化数据一起发布,因此您不会容易受到框架版本不匹配的影响。就硬件架构而言,.NET已经为您处理好了。 - Sergey Kalinichenko

0
你可以使用一个 IEnumerable<yourobj>,这将让你懒惰地按需返回可枚举的对象。
但是问题在于,你不能像使用数组那样对它进行索引。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接