firstorDefault表现上升

时间:2010-08-25 10:01:27

标签: c# linq performance dictionary

部分代码:

Dictionary<Calculation, List<PropertyValue>> result = new Dictionary<Calculation, List<PropertyValue>>();
while (reader != null && reader.Read()) //it loops about 60000, and it will be bigger
{
    #region create calc and propvalue variables
    //...
    #endregion

    //this FirstOrDefault needs a lot of time
    tmpElementOfResult = result.Keys.FirstOrDefault(r => r.InnerID == calc.InnerID);
    if (tmpElementOfResult == null)
    {
        result.Add(calc, new List<PropertyValue> { propValue });
    }
    else
    {
        result[tmpElementOfResult].Add(propValue);
    }
}

你能否告诉我如何让它更快,因为现在大约是25秒:(?

3 个答案:

答案 0 :(得分:2)

听起来你应该有calc.InnerID类型的词典,而不是Dictionary<Calc, ...>。这样你就可以更快地完成查找。你真的需要存储Calc本身,还是只对ID感兴趣?

例如:

Dictionary<Guid, List<PropertyValue>> result = 
    new Dictionary<Guid, List<PropertyValue>>();
while (reader.Read())
{
    // Work out calc
    List<PropertyValue> list;
    if (!result.TryGetValue(calc.InnerID, out list))
    {
         list = new List<PropertyValue>();
         result[calc.InnerID] = list;
    }
    list.Add(propValue);
}

或者,如果您可以将阅读器转换为IEnumerable<Calc>,则可以使用:

Lookup<Guid, PropertyValue> result = items.ToLookup(x => x.InnerID,
                                                    // Or however you get it...
                                                    x => x.PropertyValue);

编辑:如果它们具有相同的InnerID,听起来应该认为两个Calc值相等,对吧?因此,在Equals中覆盖GetHashCodeCalc以引用InnerID。然后你可以使用:

Lookup<Calc, PropertyValue> result = items.ToLookup(x => x,
                                                    // Or however you get it...
                                                    x => x.PropertyValue);

...或者您可以像第一个代码段一样使用代码,但使用Dictionary<Calc, ...>

Dictionary<Calc, List<PropertyValue>> result = 
    new Dictionary<Calc, List<PropertyValue>>();
while (reader.Read())
{
    // Work out calc
    List<PropertyValue> list;
    if (!result.TryGetValue(calc, out list))
    {
         list = new List<PropertyValue>();
         result[calc] = list;
    }
    list.Add(propValue);
}

答案 1 :(得分:0)

而不是

  tmpElementOfResult = result.Keys.FirstOrDefault(r => r.InnerID == calc.InnerID);

使用

  result.ContainsKey(calc.InnerId);

检查是否存在密钥。

答案 2 :(得分:0)

是否可以做这样的事情:

                lookUpForResult = result.ToLookup(x => x.Key.InnerID, x => x.Value);

                if (lookUpForResult.Contains(calc.InnerID))
                {
                    result.Add(calc, new List<PropertyValue> { propValue });
                }
                else
                {
                   (lookUpForResult[calc.InnerID]).Add(propValue);
                }