Should I be concerned about .NET dictionary speed?
我将创建一个使用字典查找和插入相当多的项目。这是值得关注的事情吗?
另外,如果我做基准测试之类的工作,而且确实很糟糕,那么用其他东西替换字典的最佳方法是什么?使用带有"hashed"键的数组会更快吗?但这对插入时间没有帮助,是吗?
另外,我不认为我在进行微优化,因为这确实是生产服务器上代码的重要组成部分,所以如果这需要额外的100毫秒来完成,那么我们将寻找处理这一问题的新方法。
您正在进行微优化。您甚至还有工作代码吗?记住,"如果它不起作用,不管它有多快不起作用。"(Mich Ravera)http://www.codingninja.co.uk/best programmers quotes/。
你不知道瓶颈会在哪里,你已经专注于字典了。如果问题出在别的地方呢?
另外,它实际上是".net dictionaries",而不是"c dictionaries",因为c只是使用框架的几种编程语言之一。
Hello, I will be creating a project
that will use dictionary lookups and
inserts quite a bit. Is this something
to be concerned about?
对。预先考虑性能因素总是明智的。
您的问题应该采取的形式如下:您的问题应该鼓励您编写实际的、以用户为中心的性能规范。它应该鼓励您尽早开始编写性能测试,并经常运行它们,这样您就可以看到产品的每个更改如何影响性能。这样,当代码更改导致用户影响性能更改时,将立即通知您。它应该鼓励您经常运行配置文件,这样您就可以根据经验测量来推理性能,而不是随机猜测和预感。
Also, if I do benchmarking and such
and it is really bad, then what is the
best way of replacing dictionary with
something else?
最好的方法是建立一个合理的抽象层。如果您有一个表示"insert"和"lookup"抽象数据类型的类(或接口),那么您可以在不更改任何调用方的情况下替换其内部结构。
注意,添加一个抽象层本身就有一个性能成本。如果您的分析显示抽象层太昂贵,那么如果每次调用额外的几纳秒太多,那么您可能必须除去抽象层。同样,这个决定将由实际的性能数据驱动。
Would using an array with"hashed"
keys even be faster? That wouldn't
help on insert time though will it?
无论你还是任何一个读过这篇文章的人,都不可能知道哪一篇文章写得更快,除非你用两种方式来写,然后在现实条件下用两种方式来衡量它。在"实验室"条件下进行这项工作会扭曲结果;当GC处于实际内存压力下时,您需要了解事情是如何工作的,等等。你不妨问一下,在明年的肯塔基德比中,哪匹马跑得更快。如果我们只通过看赛马表就知道答案,我们都已经很富有了。您不可能期望任何人知道在未指定的条件下,两个完全假设的、未写的代码片段中的哪一个会更快!
等待,看看应用程序的性能是否低于预期如果是,则使用分析器来确定字典查找是否是问题的根源。如果是这样,那么用代表性的数据做一些测试,看看另一个列表选择是否更快。
简而言之——不,一般来说,在遇到问题之前,您不应该担心实现细节的性能。
我将对字典、hashtable(在.net中使用hashset)和本地类进行基准测试,看看在您的典型使用条件下哪一个最有效。
通常我会说这很好(在这里插入StackOverflow最喜欢的早泄引用),但如果这是应用程序、基准、基准的核心部分。
我不确定是否有人真的回答了这一部分:
Also, if I do benchmarking and such
and it is really bad, then what is the
best way of replacing dictionary with
something else?
为此,尽可能将变量声明为
1 |
我唯一能想到的是字典的速度依赖于具有相当快的gethashcode方法的key类。查找和插入非常快,所以您不应该有任何问题。
关于使用数组,字典类已经这样做了。实际上,它使用两个数组,一个用于键,一个用于值。
如果您的字典有任何性能问题,那么很容易为任何类型的存储创建一个包装器,它具有与字典相同的方法和行为,这样您就可以无缝地替换它。
如果您的应用程序是多线程的,那么性能的关键部分就是正确地同步这个字典。
如果它是单线程的,那么几乎可以肯定瓶颈会出现在其他地方。比如从你读这些东西的地方读它们。
我为UDP中继服务器使用字典。每次数据包到达时,它都执行dictionary.containskey和dictionary[key],并且工作得很好(大量客户机)。我做这件事的时候有点担心,但事实证明这是我最不应该担心的事情。
看看C混合字典的用法
HybridDictionary类
This class is recommended for cases
where the number of elements in a
dictionary is unknown. It takes
advantage of the improved performance
of a ListDictionary with small
collections, and offers the
flexibility of switching to a
Hashtable which handles larger
collections better than ListDictionary
您可以考虑使用c5库。我发现它设计得很快,很有思想。StackOverflow上的其他人也发现了同样的情况。使用c5,您可以选择使用通用类型的接口(带大写字母I),或者直接使用下面的数据结构。当然,接口允许您交换不同的实现,但我在性能测试中发现,这些接口会让您付出代价。
您可能需要查看System.ObjectModel中的keyedcollection类。在msdn描述中,"为其键嵌入到值中的集合提供抽象基类。"