更快地更新字典值

本文关键字:字典 更新 | 更新日期: 2023-09-27 17:58:50

我的字典是

Dictionary<string, string> d = new Dictionary<string, string>();

我正在遍历一个XML文件(非常大),并将键/值对保存在字典中。

下面的代码快照执行速度非常慢,我想让它更快。我的ctr值达到3332130,大约需要一个多小时才能完成。

if (d.ContainsKey(dKey))
{
    dValue = d[dKey];
    d[dKey] = dValue + "," + ctr;
}
else
    d.Add(dKey, ctr.ToString());
ctr++;

更快地更新字典值

3332130是一个存储在内存中的大数字,您不应该在内存中保存这么大的集合。

话虽如此,让我们试着优化一下。

Dictionary<string, StringBuilder>() d = new Dictionary<string, StringBuilder>();
StringBuilder builder;
if (d.TryGetValue(dKey, out builder))
{
    builder.Append(",");
    builder.Append(ctr);
}
else
{
   d.Add(dKey, new StringBuilder(ctr.ToString()));
}
  1. 紧密循环中的字符串串联非常慢,请使用改为StringBuilder
  2. 使用TryGetValue可以避免调用dValue = d[dKey];

我认为这将大大提高性能。

在编译时对大字符串执行许多未知的重复串联是一件固有的浪费行为。如果你最终将许多值连接在一起,并且它们不是特别小,那么很容易成为问题的根源。

如果是这样的话,那就和字典没有任何关系了。您应该考虑使用StringBuilder,或者建立一个单独的字符串集合,当您拥有该值所需的所有字符串时,可以使用string.Join连接这些字符串。

可能希望考虑使用StringBuilders而不是字符串:

var d = new Dictionary<string, StringBuilder>();

并附加如下值:

if (d.ContainsKey(dKey))
{
    d[dKey].Append("," + ctr);
}
else
    d.Add(dKey, new StringBuilder(ctr.ToString()));
++ctr;

但我怀疑瓶颈实际上在其他地方。

除了字符串连接增强功能外,您还可以将XML拆分为多个数据集,然后与它们并行填充ConcurrentDictionary。根据您使用的数据和框架,性能可能会随着时间的推移而提高。

此处和此处的更多示例