我有一本德尔福词典,TDictionary<key,value>里面有几万对。值是带有字符串的记录。我需要根据某种条件一次性删除大约 10..90% 的对(通过按键,如果这很重要)。过滤器/条件预先未知。问题是如何有效地做到这一点(不浪费额外的时间和内存)?
例如,这是不正确的(在Delphi 11中),会留下额外的元素:
for var i in Dict.Keys do
if i ... then
Dict.Remove(i);
如果是TList<>,那么一切都很简单 - 我们从尾部迭代到头部Delete(I)(或者更好的是,使用第二个计数器,替换不必要的元素并在末尾切断)。
创建一个包含 1300 万个元素的字典,花费了 5.1 秒。
已删除 删除具有偶数键的元素 - 花费了 1.2 秒。似乎没有什么值得争的...
删除是由 执行的
function TDictionary<K,V>.DoRemove,在其代码中整个哈希表的铲除(例如永久数组移位)是不可见的。在删除帮助中:This is an O(1) operation已更改 -
Dict.Keys.ToArray创建键数组的副本。输出到~i5-4440(时间以毫秒为单位,字典大小)
输出最后一个片段的两次重复
测试代码:
以及 Delphi 11.3 在 i7-1355U 上调试的结果。经过多次运行测试,包括 无序 - 相对时间 +/- 相同。在 Release 中,一切都快一点,但相对值的分布方式相同: