我将创建一个需要频繁使用字典查找和插入的项目。这个会不会成为一个问题?
如果我进行基准测试,结果很差,那么用什么替代字典是最好的方式?使用带有“哈希”键的数组是否更快呢?但这对于插入时间没有帮助,对吗?
此外,我认为我并没有微优化,因为这确实会是生产服务器上代码的一个重要部分,所以如果这需要额外100毫秒才能完成,那么我们将寻找新的处理方式。
我将创建一个需要频繁使用字典查找和插入的项目。这个会不会成为一个问题?
如果我进行基准测试,结果很差,那么用什么替代字典是最好的方式?使用带有“哈希”键的数组是否更快呢?但这对于插入时间没有帮助,对吗?
此外,我认为我并没有微优化,因为这确实会是生产服务器上代码的一个重要部分,所以如果这需要额外100毫秒才能完成,那么我们将寻找新的处理方式。
你正在进行微观优化。你是否已经有运行的代码?记住,“如果它不工作,那么它有多快也没关系。”(Mich Ravera) http://www.codingninja.co.uk/best-programmers-quotes/.
你不知道瓶颈在哪里,现在就专注于字典了。如果问题出在别的地方呢?
你怎么知道Dictionary类是如何实现的?也许它已经使用了带有哈希键的数组!
P.S. 真正的“ .NET Dictionaries” 而不是“ C# Dictionaries”,因为C#仅是使用该框架的几种编程语言之一。
你好,我将创建一个需要频繁使用字典查找和插入的项目。这个会有什么问题吗?
是的,始终要考虑性能因素。你应该关注以下几点:写出现实的、以用户为中心的性能规范;尽早编写性能测试,并经常运行它们,以便了解每个对产品的更改如何影响性能。这样,当代码更改导致性能发生影响时,你可以立即得到通知。此外,你应该经常进行性能分析,这样你就可以根据实际测量结果而不是随意猜测来思考性能。
如果我的基准测试结果差强人意,那么用别的东西替换字典的最佳方法是什么?
最好的方法是构建一个合理的抽象层。如果你有一个表示“插入”和“查找”抽象数据类型的类(或接口),那么你可以替换其内部而不改变任何调用者。
请注意,添加抽象层本身会带来性能成本。如果你的性能分析表明抽象层过于昂贵,如果每次调用额外的几个纳秒时间太多,那么你可能必须摆脱这个抽象层。同样,这个决策将受到真实世界性能数据的驱动。
使用带有“哈希”键的数组是否更快?但这对插入时间没有帮助,对吗?
在真实环境下,无论是你还是任何人都不可能知道哪一个方案更快,除非你同时编写并在真实情况下对其进行基准测试。 在“实验室”条件下进行测试会导致结果偏差;你需要了解在GC受到现实内存压力时的工作原理等等。这就好比让我们预测明年肯塔基德比赛中哪匹马将跑得更快一样。如果我们仅凭比赛记录就能猜出答案,我们早已致富了。你不可能指望有人知道两个完全假设、未编写的代码片段在未指定条件下哪一个更快!
Dictionary<TKey, TValue>
类实际上是以哈希表的形式实现,使查找非常快速(接近O(1))。有关更多信息,请参见API文档。我怀疑你自己也无法做出更好的实现。
如果您的应用程序的性能低于预期,请先观察一段时间
如果确实如此,那么请使用分析器确定字典查找是否是问题的源头
如果确实是这样,请使用代表性数据进行测试,以查看选择另一个列表是否会更快。
总之 - 通常情况下,在出现问题之前不必担心实现细节的性能。
我建议您对字典、哈希表(在.NET中为HashSet)以及可能的自定义类进行基准测试,看看在您的典型使用条件下哪个效果最好。
通常情况下,我会说这没问题(插入StackOverflow最喜欢的“过早乐观”的名言),但如果这是应用程序的核心部分,请务必进行基准测试。
IDictionary<string, int> myDict = new Dictionary<string, int>();
如果您的应用程序是多线程的,那么性能的关键部分将是正确同步此字典。
如果它是单线程的,则几乎肯定瓶颈将在其他地方。例如从任何地方读取这些对象。
我使用字典作为UDP中继服务器。每次数据包到达时,它会执行Dictionary.ContainsKey和Dictionary[Key],效果非常好(有大量的客户端)。在制作过程中我曾经有些担心,但现在看来这是我最不应该担心的事情。
推荐在字典中元素数量未知的情况下使用此类。它利用了ListDictionary在小集合中的改进性能,并提供了灵活性,可以切换到Hashtable,在处理大集合时比ListDictionary更优秀。