3

我在我的程序中广泛使用哈希映射数据结构。我正在使用 Barry Kelly 在 Codegear 论坛上发布的哈希映射实现。该实现在内部使用 RTL 的 CompareText 函数。分析让我意识到在 SysUtils CompareText 函数上花费了很多时间。

我看了看

快码网站

并找到了一些更快的 CompareText 实现。不幸的是,它们似乎不适用于 D2009 及其 unicode 字符串。

现在的问题是:是否有类似的更快的版本支持 D2009 字符串?在使用哈希映射时,CompareText 函数似乎被调用了很多(至少在我当前使用的实现中),所以很少的性能改进真的会产生影响。或者那里提供的实现也适用于 unicode 字符串?

4

1 回答 1

4

许多 FastCode 函数可能会在 Delphi 2009 中编译并看起来工作得很好,但它们并不适合所有输入。在汇编器中实现的那些将失败,因为它们假设字符每个只有一个字节。在 Delphi 中实现的效果会好一些,但有时它们仍然会返回不正确的结果,因为旧CompareText的“不区分大小写”的概念是基于 ASCII 而新的概念应该基于 Unicode。除了大小写之外,哪些字符被视为相同的规则对于Unicode 与它们对于 ASCII的规则有很大不同。

Andreas 在下面的评论中说 UnicodeCompareText仍然使用 ASCII 大小写比较规则,因此一些 FastCode 函数应该可以正常工作。在使用它们之前检查它们以确保它们没有做出任何字符大小的假设。我似乎记得一些FastCode 函数已经被合并到 Delphi RTL 中。我不知道是否CompareText是其中之一。

如果您CompareText在哈希表中调用了很多,那么这表明您的哈希表做得不是很好。CompareText仅当您要搜索的事物的哈希在哈希表中指定为非空存储桶时才应被调用。从那里开始,哈希表通常会使用线性搜索在桶中找到正确的项目,并且CompareText在搜索过程中它会调用每个项目。不知道你用的那个是不是这样。

您可以通过使用不同的散列函数来解决这个问题,该函数将其结果更均匀地分布在可用的存储桶上。如果您的桶已经被均匀填充,那么您可能需要更多桶(然后确保哈希函数仍然均匀分布在数字上)。

如果您使用的 hash-map 类是基于 的TBucketList,那么桶存储还有改进的空间。该类不会计算整个输入的哈希值。它仅使用输入来确定要使用的存储桶。如果该类还跟踪为字符串计算的完整哈希,那么线性搜索期间的比较可能会更快。只需比较哈希,并且仅在哈希完全匹配时才比较字符串。(对于 256 桶桶列表,支持的最大大小,只有一个字节的输入决定桶,其余字节被忽略。)我之前写过TBucketList这里。

于 2009-03-04T17:16:59.073 回答