我将创建一个将使用字典查找和插入相当多的项目。这是值得关注的吗?
另外,如果我进行基准测试并且确实很糟糕,那么用其他东西替换字典的最佳方法是什么?使用带有“散列”键的数组会更快吗?那会对插入时间有所帮助吗?
另外,我不认为我是微优化的,因为这确实是生产服务器上代码的重要组成部分,所以如果这需要额外的100ms来完成,那么我们将寻找新的方法来处理这个(事情。
答案 0 :(得分:78)
您是微优化。你甚至还有工作代码吗?请记住,“如果它不起作用,那么快速如何不起作用并不重要。” (Mich Ravera)http://www.codingninja.co.uk/best-programmers-quotes/。
您不知道瓶颈会在哪里,而且您已经专注于词典。如果问题出在其他地方怎么办?
P.S。它实际上是“.NET Dictionaries”,而不是“C#Dictionaries”,因为C#只是使用框架的几种编程语言之一。
答案 1 :(得分:65)
您好,我将创建一个项目 这将使用字典查找和 插入相当多。这是什么东西 要关注?
是。预先考虑性能因素总是明智的。
您应关注的形式如下:您的关注应该是鼓励您编写切合实际的,以用户为中心的性能规范。应该鼓励您尽早开始编写性能测试并经常运行它们,这样您就可以看到产品的每一次更改都会影响性能。这样,当代码更改导致影响用户的性能变化时,您将立即得到通知。它应该鼓励你经常运行配置文件,这样你就可以根据经验测量来推断性能,而不是随机猜测和预测。
另外,如果我做基准测试等 它真的很糟糕,然后是什么 用词替换词典的最佳方法 别的什么?
执行此操作的最佳方法是构建合理的抽象层。如果您有一个表示“插入”和“查找”抽象数据类型的类(或接口),则可以在不更改任何调用者的情况下替换其内部。
请注意,添加一个抽象层本身会带来性能成本。如果您的分析显示抽象层太昂贵,如果每次调用额外的几纳秒太多,那么您可能不得不摆脱抽象层。同样,这个决定将由现实世界的性能数据驱动。
使用带有“哈希”的数组 键甚至更快?那不会 有关插入时间的帮助吗?
你或任何阅读此内容的人都不可能知道哪一个更快,直到你以两种方式编写它,然后在真实条件下对它进行基准测试。在“实验室”条件下进行此操作会使您的结果产生偏差;当GC处于实际内存压力下时,您需要了解其工作原理,等等。你不妨问我们明年肯塔基德比赛中哪匹马会跑得更快。如果我们只是通过观察比赛形式就知道答案,我们都已经变得富有了。在未指定的条件下,你不可能指望任何人知道两个完全假设的,不成文的代码中的哪一个会更快!
答案 2 :(得分:10)
Dictionary<TKey, TValue>
类实际上是作为哈希表实现的,它使查找速度非常快(接近O(1))。有关详细信息,请参阅the API documentation。我怀疑你自己能做出更好的实施。
答案 3 :(得分:10)
等一下,看看您的应用程序的性能是否低于预期 如果是,则使用分析器确定字典查找是否是问题的根源 如果是,那么使用代表性数据进行一些测试,看看是否有更快的选择列表。
简而言之 - 不,一般情况下,在遇到问题之前,您不应该担心实施细节的效果。
答案 4 :(得分:5)
我会做一下Dictionary,HashTable(.NET中的HashSet),也许是一个本土的类的基准测试,看看哪种方法在你的典型使用条件下效果最好。
通常我会说没关系(在这里插入StackOverflow最喜欢的早泄名称),但如果这是应用程序的核心,Benchmark,Benchmark,Benchmark。
答案 5 :(得分:4)
我能想到的唯一问题是字典的速度依赖于具有相当快的GetHashCode方法的密钥类。查找和插入非常快,所以你不应该有任何问题。
关于使用数组,这就是Dictionary类已经做的事情。实际上它使用两个数组,一个用于键,一个用于值。
如果你对Dictionary有任何性能问题,那么为任何类型的存储创建一个包装器会非常容易,它具有与Dictionary相同的方法和行为,因此你可以无缝地替换它。
答案 6 :(得分:4)
我不确定是否有人真的回答过这一部分:
另外,如果我做基准测试等 它真的很糟糕,然后是什么 用词替换词典的最佳方法 别的什么?
为此,尽可能将变量声明为IDictionary<TKey, TValue>
。这是Dictionary派生的主要界面。 (我假设如果你非常关心性能,那么你不会考虑非泛型集合。)然后,在将来,您可以更改底层实现类,而无需更改任何使用该代码的代码。字典。例如:
IDictionary<string, int> myDict = new Dictionary<string, int>();
答案 7 :(得分:2)
如果你的应用程序是多线程的,那么性能的关键部分就是正确地同步这个字典。
如果它是单线程的,那么几乎可以肯定的瓶颈将在其他地方。比如从你阅读它们的任何地方读取这些物体。
答案 8 :(得分:1)
建议将此类用于案例 其中元素的数量 字典未知。它需要 提高性能的优势 一个ListDictionary的小 收藏品,并提供 切换到的灵活性 Hashtable处理更大 集合优于ListDictionary
答案 9 :(得分:1)
我使用Dictionary for UDP中继服务器。每次数据包到达时,它执行Dictionary.ContainsKey和Dictionary [Key],它工作得很好(大量的客户端)。我在做这件事时有些担心,但事实证明这是我应该担心的最后一件事。
答案 10 :(得分:0)
您可以考虑使用C5库。我发现它非常快速且经过精心设计。 stackoverflow上的其他人也发现了相同的情况。使用C5,您可以选择使用通用类型接口(使用captial I),或直接使用下面的数据结构。当然,接口允许您交换不同的实现,但我在性能测试中发现接口将花费您。
答案 11 :(得分:-3)
您可能希望查看System.ObjectModel中的KeyedCollection类。从MSDN描述中,“为其键嵌入值的集合提供抽象基类。”