Does the length of key affect Dictionary performance?
我将在.NET项目中使用字典来存储大量对象。因此,我决定使用GUID字符串作为键,以确保每个对象的唯一键。
大键(例如GUID(或更大的键))是否会降低字典的性能,例如通过其键检索对象?
谢谢,
安德烈(Andrej)
我建议使用实际的Guid而不是Guid的字符串表示形式。是的,在比较字符串时,长度确实会影响所需的操作次数,因为它必须逐个字符地比较字符串(最低限度;不包括任何特殊选项,例如IgnoreCase)。实际的Guid将只给您提供16个字节进行比较,而不是string中的最小值32个。
话虽这么说,您很可能不会注意到任何区别...过早的优化以及所有这些。我只是选择Guid键,因为这就是数据。
-
实际上,对Guid进行哈希处理比对32个字符串进行哈希处理要快得多。 1个
-
谢谢,听起来合理。
-
CLR的字符串实习怎么样? (内部创建的哈希表,用于跟踪字符串)
与获取值有关的对象的实际大小无关紧要。查找值的速度更多地取决于传入的IEqualityComparer<T>实例
中的两种方法的速度
编辑
许多人以String为由说更大的对象大小会降低查找性能。出于某些原因,必须与一粒salt一起服用。
-
对于默认比较器,上述方法的性能随着字符串大小的增加而降低。仅仅因为System.String是正确的,并不意味着它通常是正确的
-
您可以以与字符串长度无关的方式轻松地编写不同的IEqualityComparer<String>。
-
首先,您仍然必须遍历字符串以进行比较,因此无论使用哪种算法,大小都会影响性能。
-
@Blindy不,你不知道。这完全取决于我在比较器中认为相等的字符串。也许我只关心前3个字母的前缀?也许只有第一个字母。或者我只是说非空字符串是相等的。随着字符串变大,这些大小都不会变化
-
那时这似乎不适用于OP,他需要对类似guid的键进行全面比较。
-
@Blindy我将OP的问题更一般地阅读了。除此之外,那些说String关键演奏与其长度直接相关的人都是错误的。这是IEqualityComparer <TKey>的问题,而不是密钥本身。
-
@Jared:他们不是"完全错误"。在默认情况下(可以说是MOST情况),存在直接关联。即使是最常用的替代方法,StringComparer.*IgnoreCase仍然会逐个字符移动(显然,直到找不到匹配项为止)。
-
@Adam,我并不是想引起争议,但是说String键大小会直接影响性能是错误的。这可能是最可能的默认情况,但这是一个错误的断言。您根本无法查看"字典"的"键"类型,也无法对查询的性能特征做出明确的陈述。仅知道IEqualityComparer <TKey>的详细信息才能为您提供此信息。
-
@Jared:是的,显然你是对的。您可以实现为O(1)的IEqualityComparer<T>(用于string或其他任何东西)。但是,那是极不可能的。您所做出的区分是学术性的,我想会引起更多的混乱,而不是增加清晰度。
-
@Adam,我不同意这是一次学术讨论,特别是因为我已经确切地看到了这些类型的IEqualityComparer<T>实现(超过1种)。在至少一种情况下,这是个好主意,并适合这种情况。仅仅因为它不太可能并不意味着您不会遇到它。
-
@Jared:是的,正如我所说,这不太可能。如果我的意思是您不会遇到它,那么我会说它根本不会发生;)那么,我们同意不同意。
-
@亚当,同意了。我看到的代码越多,我就不再理会更多的事情了:(
是,不是。较大的字符串会增加字典的内存大小。而更大的大小意味着略微更长的时间来计算哈希大小。
但是担心这些事情可能是过早的优化。尽管速度会变慢,但您可能不会真正注意到它。
请参阅性能-使用Guid对象或Guid字符串作为键来解决类似问题。您可以使用替代密钥进行测试。
我在Google上进行了快速搜索,找到了这篇文章。
http://dotnetperls.com/dictionary-string-key
它确认通常较短的键比较长的键的性能更好。
-
这并不是一个很好的测试,因为当比较2个和20个字符的键时,显示1亿次字典查找仅可提高3秒的性能。在字典的大多数使用中,这并不是很大的收获。在现实世界中,我发现字典的每一种用法,性能提升都将达到纳秒级。因此,您的说法"通常较短的键比较长的键性能更好"。"一般",这是微不足道的。
显然是的。这是一个很好的测试:字典字符串键测试
- 这不是一个很好的测试,因为当比较2个和20个字符的键时,它进行1亿次字典查找时,性能仅提高3秒。在字典的大多数使用中,这并不是很大的收获。
-
2个字符:1.5秒。 20个字符:4.5秒。由于这3秒总计提高了3倍,我认为这很重要。当然,只要字典查找是处理中最慢的步骤。