如果我有一个颜色名称的静态列表及其十六进制等效项,那么使用最快的数据结构是什么?

0 .net c# structure .net-core

使用.net核心,所以我无权访问System.Drawing.我有一个865颜色名称及其十六进制等效的列表(0x格式).我永远不需要修改列表,我只需要能够从Either列快速搜索列表(可以搜索名称或十六进制).名称很简单,按字母顺序排列,但Hex是它们的名称.我想让它快速找到对方搜索的方式吗?什么是创建数据结构的最佳方法,以及您将使用哪些搜索方法?

我正在研究http://cc.davelozinski.com/c-sharp/fastest-collection-for-string-lookups

它显示了一些有趣的数据,但它只搜索单个列,所以不是我正在寻找的.如果我只使用颜色名称作为键值,排序列表似乎是要走的路,但是Hex会让我失望.

示例列表:

Air superiority blue    0x72A0C1 
Alabama Crimson     0xA32638 
Alice blue  0xF0F8FF 
Alizarin crimson    0xE32636 
Alloy orange    0xC46210 
Almond  0xEFDECD 
Amaranth    0xE52B50 
Amber   0xFFBF00 
Run Code Online (Sandbox Code Playgroud)

410*_*one 5

如果你有一个静态列表(变化非常罕见,可以忽略不计),并且你需要立即,超高速访问,你可以使用许多简单的C#功能之一,我将概述2个主要选项:switch或者Dictionary,您需要两个用于最快的方法.

您可以使用程序为您生成代码,但示例如下:

开关/箱

第一个例子很简单,构建两个方法,GetHexFromName并在其中GetNameFromHex包含一个switch语句.

public static int GetHexFromName(string name)
{
    switch (name)
    {
        case "Amaranth":
            return 0xE52B50;
        case "Amber":
            return 0xFFBF00;
        // Remaining 863 colors
        default:
            throw new ArgumentException();
    }
}

public static string GetNameFromHex(int hex)
{
    switch (hex)
    {
        case 0xE52B50:
            return "Amaranth";
        case 0xFFBF00:
            return "Amber";
        // Remaining 863 colors
        default:
            throw new ArgumentException();
    }
}
Run Code Online (Sandbox Code Playgroud)

很容易.你可以构建一个可以为你生成代码的快速工具,Roslyn可能会让它更容易.

你会称之为GetHexFromName(colorName).

字典

这可能是我将要采用的方法,因为访问读得更好.

public static readonly ReadOnlyDictionary<string, int> Hex = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> {
    ["Amber"] = 0xE52B00,
    ["Amaranth"] = 0xFFBF00,
    // Remaining 863
});

public static readonly ReadOnlyDictionary<int, string> Name = new ReadOnlyDictionary<int, string>(new Dictionary<int, string> {
    [0xE52B00] = "Amber",
    [0xFFBF00] = "Amaranth",
    // Remaining 863
});
Run Code Online (Sandbox Code Playgroud)

这读为Hex[colorName].

可以轻松调整其中任何一个以将十六进制格式化为字符串格式.该ReadOnlyDictionary是在System.Collections.ObjectModel命名空间中的System.Collections.dll库..NET Core版本可能没有,因此您可能需要从代码中省略它.只要相信没有人会在Dictionary类型上调用任何方法.我也为C#6.0语法编写了这个 - 你可能需要为你的环境改变它.


这些将是您最快的选择,特别是如果列表不经常更改(或根本不改变).唯一的问题是可维护性,但通常你会牺牲其中一个:可维护性,性能,简单性.在这里,我们牺牲了一点可维护性,但我们获得了很多性能.

此外,在这两种情况下,顺序都不重要:在switch选项中,编译器将生成最佳代码(我们希望),在Dictionary选项中,JITter和Dictionary实现将优化结构.阅读其中任何一个都应该很快.

  • @MickyD Switch和[字典访问](https://msdn.microsoft.com/en-us/library/9tee9ht2(v = vs.110).aspx)在框架中记录为O(1).(Switch可能没有记录为O(1),但它构建了一个跳转表,在大多数平台上实际上是一条带O(1)的指令.) (2认同)