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

时间:2017-04-12 05:22:38

标签: c# .net 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 

2 个答案:

答案 0 :(得分:5)

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

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

开关/案例

第一个示例很简单,在其中构建两个方法GetHexFromNameGetNameFromHex以及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();
    }
}

够容易。你可以构建一个可以为你生成代码的快速工具,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
});

这读为Hex[colorName]

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

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

此外,在这两种情况下,顺序都无关紧要:在switch选项中,编译器将生成最佳代码(我们希望),在Dictionary选项中生成JITter和{{ 1}}实现将优化结构。从这些中的任何一个读取都应该快速

答案 1 :(得分:-1)

少于1000行 - 你决定这样做的任何方式都可以忽略不计 -

1)老式词典(可能是最简单的方法) - hxxps://msdn.microsoft.com/en-us/library/xfhwa508(V = vs.110)的.aspx

不是最漂亮的方法:使用数据表在应用程序中创建静态类:hxxps://msdn.microsoft.com/en-us/library/system.data.datatable(v = vs.110).aspx < / p>

您可以在实例化类时对这些值进行硬编码,或者从单独的数据源中提取它们(如果您真的关心性能,请对值进行硬编码)。

使用此方法,您将能够使用select语句返回整行:hxxps://msdn.microsoft.com/en-us/library/det4aw50(v = vs.110).aspx

前:

DataTable Table = class.datatable();
// Datatable class created with 2 columns: color,hex
string expression = "color = Almond"; //or "hex = 0xEFDECD"
DataRow[] foundRows;
foundRows = Table.Select(expression);

Foundrows [0]将等于杏仁 foundRows [1]将等于十六进制值

您也可以使用静态JSON对象或数组执行相同的操作,并使用LINQ进行搜索:hxxp://newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm

我有兴趣比较三者之间的性能,但是不到1000行 - 没有真正对整个数据集进行性能测试......我会说出最简单的说法最快的表现将是字典。

注意:我的排名低于10 - 您需要在链接中将'hxxp'替换为'http'。