我应该关注.NET字典的速度吗?

我将创建一个将使用字典查找和插入相当多的项目。 这是值得关注的吗?

此外,如果我进行基准测试等并且它真的很糟糕,那么用其他东西替换字典的最佳方法是什么? 使用带有“哈希”键的数组会更快吗? 那会对插入时间有所帮助吗?

此外,我不认为我是微优化的,因为这确实是生产服务器上代码的重要组成部分,因此如果需要额外的100毫秒才能完成,那么我们将寻找新的方法来处理这个问题。

  1. 微观优化。 你甚至还有工作代码吗? 请记住,“如果它不起作用,它无效的速度无关紧要。” (Mich Ravera) http://www.codingninja.co.uk/best-programmers-quotes/

    你不知道瓶颈会在哪里,而且你已经专注于词典。 如果问题出在其他地方怎么办?

  2. 你怎么知道Dictionary类是如何实现的? 也许它已经使用了带有散列键的数组!

PS它实际上是“.NET Dictionaries”,而不是“C#Dictionaries”,因为C#只是使用该框架的几种编程语言之一。

您好,我将创建一个将使用字典查找和插入相当多的项目。 这是值得关注的吗?

是。 预先考虑性能因素总是明智的。

您需要考虑的forms如下:您的关注应该是鼓励您编写切合实际的,以用户为中心的性能规范。 它应该鼓励您尽早开始编写性能测试并经常运行它们,这样您就可以看到产品的每一次更改如何影响性能。 这样,当代码更改导致影响用户的性能变化时,您将立即得到通知。 它应该鼓励你经常运行配置文件,这样你就可以根据经验测量推断性能,而不是随机猜测和预测。

此外,如果我进行基准测试等并且它真的很糟糕,那么用其他东西替换字典的最佳方法是什么?

最好的方法是构建一个合理的抽象层。 如果您有一个表示“插入”和“查找”抽象数据类型的类(或接口),则可以在不更改任何调用者的情况下替换其内部。

请注意,添加抽象层本身会产生性能成本。 如果您的分析显示抽象层太昂贵,如果每次调用额外的几纳秒太多,那么您可能不得不摆脱抽象层。 同样,这个决定将由现实世界的性能数据驱动。

使用带有“哈希”键的数组会更快吗? 那会对插入时间有所帮助吗?

无论是你还是读过这篇文章的人都不可能知道哪一个更快,直到你用两种方式写它,然后在真实条件下以两种方式对它进行基准测试。 在“实验室”条件下进行此操作会使您的结果出现偏差; 当GC处于实际内存压力下时,您需要了解其工作原理,等等。 你不妨问我们明年的肯塔基赛马会哪匹马跑得更快。 如果我们只是通过观察比赛forms就知道了答案,那么我们都已经变得富有了。 在未指定的条件下,你不可能指望任何人知道两个完全假设的,不成文的代码中的哪一个会更快!

等一下,看看你的应用程序的性能是否低于预期
如果是,则使用分析器确定字典查找是否是问题的根源
如果是,那么用代表性数据进行一些测试,以查看列表的另一个选择是否更快。

简而言之 – ,一般来说,在遇到问题之前,您不应该担心实现细节的性能。

Dictionary类实际上是作为哈希表实现的,它使查找非常快(接近O(1))。 有关更多信息,请参阅API文档 。 我怀疑你自己可以做出更好的实施。

我会做一下Dictionary的基准测试,HashTable(.NET中的HashSet),也许是一个本土的类,看看哪些在你的典型使用条件下效果最好。

通常我会说这很好(插入StackOverflow最喜欢的早泄引用), 但如果这是应用程序的核心,Benchmark,Benchmark,Benchmark。

我能想到的唯一问题是字典的速度依赖于具有相当快的GetHashCode方法的密钥类。 查找和插入非常快,所以你不应该有任何问题。

关于使用数组,这就是Dictionary类已经做的。 实际上它使用两个数组,一个用于键,一个用于值。

如果您对Dictionary有任何性能问题,那么为任何类型的存储创建包装都会非常容易,它具有与Dictionary相同的方法和行为,因此您可以无缝地替换它。

我不确定是否还有人真正回答过这一部分:

此外,如果我进行基准测试等并且它真的很糟糕,那么用其他东西替换字典的最佳方法是什么?

为此,尽可能将变量声明为IDictionary 。 这是Dictionary派生的主要接口。 (我假设如果你非常关心性能,那么你不会考虑非generics集合。)然后,在将来,您可以更改底层实现类,而无需更改任何使用该代码的代码。字典。 例如:

 IDictionary myDict = new Dictionary(); 

如果你的应用程序是multithreading的,那么性能的关键部分就是正确地同步这个字典。

如果它是单线程的,那么几乎肯定会出现其他地方的瓶颈。 比如从你阅读它们的任何地方读取这些对象。

看看C#HybridDictionary用法

HybridDictionary类

对于字典中元素数量未知的情况,建议使用此类。 它利用了具有小集合的ListDictionary的改进性能,并提供了切换到Hashtable的灵活性,Hashtable比ListDictionary更好地处理更大的集合

我使用Dictionary for UDP relay server。 每次数据包到达时,它执行Dictionary.ContainsKey和Dictionary [Key],它工作得很好(大量的客户端)。 当我制作东西时我有些担心,但事实certificate这是我应该担心的最后一件事。

您可以考虑使用C5库。 我发现它非常快速且经过精心设计。 stackoverflow上的其他人也发现了相同的结果。 使用C5,您可以选择使用通用类型接口(带有captial I),或直接使用下面的数据结构。 当然,接口允许您交换不同的实现,但我在性能测试中发现接口将花费您。

您可能希望查看System.ObjectModel中的KeyedCollection类。 从MSDN描述中,“为其键嵌入值的集合提供抽象基类”。