除了dictionary.add之外,还有更快的方法在C#字典中添加行吗?

时间:2015-09-30 10:57:13

标签: c# dictionary

我们使用带有键值对的字典作为字符串,字典在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()时性能会受到影响。让我们知道如何优化向字典添加行,任何可以使用的外部自定义库?

2 个答案:

答案 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;
                } 
}