C#批量添加到已排序列表

C#批量添加到已排序列表,c#,list,sorting,bulk,C#,List,Sorting,Bulk,我正在寻找在两种不同条件下使用排序列表或数组的最快、最有效的方法。我想要我的蛋糕,也要吃 首先,我需要将数百个键/值对(可能多达20000个)批量添加到列表/数组中,然后按键对它们进行排序。快速排序可能是最好的方法,找出插入点并在每次添加后洗牌项目当然不是。 之后,我需要偶尔根据需要将键/值对添加到列表/数组中,并将它们插入到正确的位置。每次插入后重新运行快速排序可能不是最好的方法。 当然,我希望对其进行排序的原因是快速查找B树,以根据键查找值。 [仅供参考:在一种情况下,键是一个Guid,值是

我正在寻找在两种不同条件下使用排序列表或数组的最快、最有效的方法。我想要我的蛋糕,也要吃
首先,我需要将数百个键/值对(可能多达20000个)批量添加到列表/数组中,然后按键对它们进行排序。快速排序可能是最好的方法,找出插入点并在每次添加后洗牌项目当然不是。
之后,我需要偶尔根据需要将键/值对添加到列表/数组中,并将它们插入到正确的位置。每次插入后重新运行快速排序可能不是最好的方法。
当然,我希望对其进行排序的原因是快速查找B树,以根据键查找值。
[仅供参考:在一种情况下,键是一个Guid,值是一个带字符串的结构或简单类(人性化名称)和一对整数。在另一种情况下,字符串是键。不幸的是,字符串/名称不能保证唯一。所有内容都保存在RAM中,因为速度和对用户的响应至关重要。批量添加的所有初始数据都是由另一个应用程序生成的,我无法控制。]
我对如何编写一个助手类来实现这一点有一些想法,但我不想重新发明轮子。然而,我无法找到一种使用内置列表或集合类来实现这一点的方法。SortedList类似乎没有批量添加,常规列表或数组类(一旦排序)也没有按键插入的方法


<>建议>

你应该考虑使用A代替List,只要你只在键而不是值的基础上搜索元素。当试图获取单个键的值时,这是一个O(1)操作,而不是必须进行多次比较才能在列表中找到相同的对象

var dictionary = new Dictionary<string, string>
{
    {"e11a5c0e-58b4-4f3c-86b8-6a127fff6ee8", "A"},
    {"7c1fdecf-7f75-4538-8805-50a67652a5a3", "B"},
    {"fed8892c-bb18-4fe3-8e31-8e287afa9243", "C"}
};

if (dictionary.TryGetValue("fed8892c-bb18-4fe3-8e31-8e287afa9243", out var value))
{
    Console.WriteLine($"The value is: {value}");
}
var字典=新字典
{
{“e11a5c0e-58b4-4f3c-86b8-6a127fff6ee8”,“A”},
{“7c1fdecf-7f75-4538-8805-50a67652a5a3”,“B”},
{“fed8892c-bb18-4fe3-8e31-8e287afa9243”,“C”}
};
if(字典TryGetValue(“fed8892c-bb18-4fe3-8e31-8e287afa9243”,输出var值))
{
WriteLine($“值为:{value}”);
}

另外,如果您可以避免使用GUID并使用连续的
int
long
,则可以将其添加到列表的末尾,对吗?不管你如何处理它,当你使用GUID作为你的密钥时,你总是需要做一些比较来插入和交换其他元素来保持列表的排序。

你应该考虑使用A代替“代码>列表< /C>”,只要你只在键而不是值的基础上搜索元素。当试图获取单个键的值时,这是一个O(1)操作,而不是必须进行多次比较才能在列表中找到相同的对象

var dictionary = new Dictionary<string, string>
{
    {"e11a5c0e-58b4-4f3c-86b8-6a127fff6ee8", "A"},
    {"7c1fdecf-7f75-4538-8805-50a67652a5a3", "B"},
    {"fed8892c-bb18-4fe3-8e31-8e287afa9243", "C"}
};

if (dictionary.TryGetValue("fed8892c-bb18-4fe3-8e31-8e287afa9243", out var value))
{
    Console.WriteLine($"The value is: {value}");
}
var字典=新字典
{
{“e11a5c0e-58b4-4f3c-86b8-6a127fff6ee8”,“A”},
{“7c1fdecf-7f75-4538-8805-50a67652a5a3”,“B”},
{“fed8892c-bb18-4fe3-8e31-8e287afa9243”,“C”}
};
if(字典TryGetValue(“fed8892c-bb18-4fe3-8e31-8e287afa9243”,输出var值))
{
WriteLine($“值为:{value}”);
}

另外,如果您可以避免使用GUID并使用连续的
int
long
,则可以将其添加到列表的末尾,对吗?无论您如何操作,当您使用GUID作为密钥时,您总是需要进行多次比较,以插入和交换其他元素以保持列表的有序性。

您能用简单的术语解释确切的问题吗?请在一个“常规”排序的
列表中按键插入
非常简单;您可以通过二进制搜索找到插入点,然后只需
List::Insert
。如果您想优化内存访问(更好地使用缓存),可以将键和值分成两个单独的数组;如果键是结构,但值不是,则特别有用。将给您顺序存储的密钥。只需通过数组中的索引将键与值关联起来。听起来你不是在重新发明轮子,而是在重新发明字典。你能用简单的术语解释一下确切的问题吗?请在一个“常规”排序的
列表中按键插入
非常简单;您可以通过二进制搜索找到插入点,然后只需
List::Insert
。如果您想优化内存访问(更好地使用缓存),可以将键和值分成两个单独的数组;如果键是结构,但值不是,则特别有用。将给您顺序存储的密钥。只需通过数组中的索引将键与值关联起来。听起来你不是在重新发明轮子——你是在重新发明字典。字典的问题与排序列表的问题相同->每次添加之后,它都要诉诸/reindex/shuffle/等。对于批量添加,这是非常低效的。我试过一些基准测试。字典不会对每一个加法都进行修改,所以它在计算散列。这是一个固定的时间操作,无论您是一次一个操作还是一次全部操作。我运行了一个基准测试,将10000个10个字符的随机字符串添加到排序列表和字典中。
SortedList
平均值为49808.8 us,而
字典平均值为943.1 us。好的,康纳,我将再次访问字典。我还(错误地)认为字典打字松散。谢谢字典的问题与排序列表的问题相同->它希望在每次添加之后使用/reindex/shuffle/等。对于批量添加,这是非常低效的。我试过一些基准测试。字典不会对每一个加法都进行修改,所以它在计算散列。这是一个恒定的时间操作,无论您是一次一个操作还是一次全部操作