简体   繁体   English

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

[英]Is there a faster way to add rows in C# dictionary other than dictionary.add?

We are using dictionary with key value pair both as string, Dictionary has millions of rows been added in a foreach loop.我们使用带有键值对的字典作为字符串,字典在 foreach 循环中添加了数百万行。 Profiler results show dictionary.add taking elapsed time in minutes for million plus hits.探查器结果显示 dictionary.add 以分钟为单位花费了超过一百万次点击的时间。

Below is the method for reference.以下方法供参考。

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

All the code lines are fine, performance is impacted when dictionaryRow.Add() is executed.所有代码行都很好,执行 dictionaryRow.Add() 时会影响性能。 Let know how do we optimise adding rows to dictionary, any external custom library which can be used ?让我们知道如何优化向字典添加行,任何可以使用的外部自定义库?

I would try changing this into a LINQ query.我会尝试将其更改为 LINQ 查询。

Maybe something like this:也许是这样的:

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

One thing to experiment is how many unique hashcodes item.ColumnNameId generates.需要试验的一件事是 item.ColumnNameId 生成了多少唯一的哈希码。 if there's a lot of collisions you are basically doing the same as iterating over a linkedlist until you reach the end and then add the object at the end.如果有很多冲突,您基本上与遍历链表相同,直到到达末尾,然后在末尾添加对象。

Here's the code that is called when you call dictionary.Add() taken from http://referencesource.microsoft.com/#q=Dictionary这是在调用来自http://referencesource.microsoft.com/#q=Dictionary 的dictionary.Add() 时调用的代码

So with a lot of collisions you start looping and comparing keys a lot and with such a large Dictionary you can expect some collisions.所以有很多的冲突开始循环和比较键很多,并与如此大的字典,你可以期待一些冲突。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM