【问题标题】:Best Algorithm for key/value pair where key is an int64 in Delphi, pre Delphi 2009?Delphi 2009 之前的键/值对的最佳算法,其中键是 int64?
【发布时间】:2008-11-11 13:15:51
【问题描述】:

我需要一种算法来存储键/值对,其中键是 Int64。我目前正在使用排序的 IntList(与 TStringList 相同,但存储 int64)。这给了我 O(log n) 的搜索、插入和删除操作。由于我不需要排序的项目,这有点低效。我需要某种用于 O(1) 操作的哈希表。问题是我能找到的大多数实现都假设键是一个字符串。现在我显然可以将 Int64 键转换为字符串,但这似乎很浪费。有什么想法吗?

我不知道输入数据结构之前的项目数。

我还应该补充一点,我已经在 .net 中使用 Dictionary 实现了相同的组件,并且它添加的项目在 .net 版本中要快得多。设置好数据结构后,比较起来,遍历和检索并没有那么糟糕,但是插入让我很头疼。

【问题讨论】:

    标签: algorithm delphi data-structures


    【解决方案1】:

    Delphi 2009 及更高版本添加了泛型。

    因此,从 Delphi 2009 开始,您可以使用 TDICTIONARY 以与在 .NET 中类似的方式实现键/值对。

    Delphi 中的 TDICTIONARY 使用的是哈希表,操作复杂度为 O(1)。

    【讨论】:

      【解决方案2】:

      您可以构建一个哈希表,其中哈希值是您添加到哈希中的 Int64 的简单模数。

      任何好的哈希表实现都会将哈希索引的生成(通过对键进行哈希处理)与其余逻辑分开。

      这里总结了一些实现:Hashtable implementation for Delphi 5

      【讨论】:

        【解决方案3】:

        您可以直接从 int64 值计算散列值,但为此您需要找到一个散列函数,它可以均匀地分配不同的 int64 值,这样您几乎不会发生冲突。这当然取决于这些键的值。如果您不知道项目的数量,您很可能也不知道这些 int64 值是如何分布的,因此想出一个好的哈希函数几乎是不可能的。

        假设您的键不是某些东西的倍数(例如地址,它将是 4、8、16 等的倍数),您可以通过使用其中几个 IntList 对象的列表来加快速度,然后先计算这个列表数组的索引。使用 mod 运算符和质数将是计算列表索引的一种简单方法。与往常一样,这是速度和内存消耗之间的权衡。

        您也可以在 google 上搜索稀疏数组的良好实现。 IIRC,Julian Bucknall 的 EZDSL 库有一个。

        【讨论】:

        • EzDsl 简单稳定,调试良好。如果您没有 Delphi 2009 或 2010,这是最好的选择。
        【解决方案4】:

        一些想法,不是一个完整的解决方案。

        除非有明确的证据表明搜索本身就是瓶颈(不要用你的“感觉”来检测瓶颈,使用代码分析器)我会坚持使用 IntList...如果实际搜索所花费的时间/insert/delete 不占总处理器时间的至少 20%,甚至不用费心。

        如果你还想要一个哈希表,那么...

        不要转换成字符串。转换将从堆中分配一个新字符串,这比搜索本身要昂贵得多。使用 int64 取模一些巧妙选择的素数作为哈希键。

        只有当哈希表足够大时,它们才会给你 O(1)。否则,您将获得大量共享相同哈希键的记录。让它太短,你会浪费你的时间搜索(线性!)通过链表。让它太大,你会浪费内存。

        请记住,哈希表需要某种形式的链表来保持所有记录共享相同的键。该链表必须通过在有效负载对象中添加“下一个”指针(这会破坏封装 - 对象不必知道它存储在哈希表中)或分配一个小的帮助对象来实现。这种分配可能比排序列表的 O(log) 成本高得多。

        【讨论】:

        • 我所做的是在 Delphi Prism/Oxygene 中实现了同样的事情。我使用了 Dictionary,在这个版本中插入速度要快得多。
        • 我同意它“快得多”,但您的整个应用程序要快多少?即使你将插入速度提高 1000 倍,如果未优化的插入只使用了总 CPU 时间的 1%,那么你一无所获。
        猜你喜欢
        • 2012-09-04
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-22
        • 2010-10-12
        相关资源
        最近更新 更多