我们使用带有键值对的字典作为字符串,字典在foreach循环中添加了数百万行。 Profiler结果显示dictionary.add花费分钟的已用时间百万加点击。
以下是参考方法。
public virtual Dictionary<string, string> CreateDictionaryRow(string[] row)
{
Dictionary<string, string> dictionaryRow = new Dictionary<string, string>();
foreach (ColumnMappingBO item in this.Layout.Items)
{
string value = string.Empty;
if (!string.IsNullOrEmpty(item.ColumnPosition))
{
if (item.ColumnPosition == "ZZ")
{
value = string.Empty;
}
else
{
if (LayoutPosition.TryGetValue(item.ColumnID, out Ordinal))
{
if (row.Length > Ordinal)
{
if (row[Ordinal] != null)
{
value = row[Ordinal];
}
}
}
}
}
dictionaryRow.Add(item.ColumnNameID, value);
}
return dictionaryRow;
}
所有代码行都很好,执行dictionaryRow.Add()时性能会受到影响。让我们知道如何优化向字典添加行,任何可以使用的外部自定义库?
答案 0 :(得分:0)
我会尝试将其更改为LINQ查询。
也许是这样的:
public Dictionary<string, string> CreateDictionaryRow(string[] row)
{
return this.Layout.Items.ToDictionary(item => item.ColumnNameID,
item => GetValue(item, row));;
}
private string GetValue(ColumnMappingBO item, string[] row)
{
string value = string.Empty;
if (!string.IsNullOrEmpty(item.ColumnPosition))
{
if (item.ColumnPosition == "ZZ")
{
value = string.Empty;
}
else
{
if (LayoutPosition.TryGetValue(item.ColumnID, out Ordinal))
{
if (row.Length > Ordinal)
{
if (row[Ordinal] != null)
{
value = row[Ordinal];
}
}
}
}
}
return value;
}
答案 1 :(得分:0)
要试验的一件事是item.ColumnNameId生成多少个唯一的哈希码。 如果有很多冲突,你基本上就像迭代一个链表一样,直到你到达最后,然后在最后添加对象。
以下是调用来自http://referencesource.microsoft.com/#q=Dictionary
的dictionary.Add()时调用的代码因此,在很多冲突的情况下,您开始循环并比较很多的键,并且使用如此大的词典,您可能会遇到一些冲突。
void Insert(TKey key, TValue value, bool add) {
if (buckets == null) Initialize(0);
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int targetBucket = hashCode % buckets.Length;
for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
entries[i].value = value;
version++;
return;
}
}