C# firstorDefault性能上升

C# firstorDefault性能上升,c#,linq,performance,dictionary,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 crea

守则的一部分:

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);
    }
}
字典结果=新建字典();
while(reader!=null&&reader.Read())//它循环大约60000次,并且会更大
{
#区域创建calc和propvalue变量
//...
#端区
//第一个默认值需要很多时间
tmpElementOfResult=result.Keys.FirstOrDefault(r=>r.InnerID==calc.InnerID);
if(tmpElementOfResult==null)
{
Add(计算,新列表{propValue});
}
其他的
{
结果[tmpElementOfResult].Add(propValue);
}
}

你能告诉我一些如何使它更快的方法吗,因为现在大约是25秒:(?

听起来你应该有一个
calc.InnerID
类型的字典,而不是
字典
。这样你可以更快地查找。你真的需要存储
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);
}
…或者您可以使用与第一个代码片段类似的代码,但要使用
字典

字典结果=
新字典();
while(reader.Read())
{
//计算
名单;
如果(!result.TryGetValue(计算,输出列表))
{
列表=新列表();
结果[计算]=列表;
}
列表。添加(propValue);
}
而不是

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


检查是否有钥匙。

是否可以执行以下操作:

                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);
                }
lookUpForResult=result.ToLookup(x=>x.Key.InnerID,x=>x.Value);
if(lookUpForResult.Contains(calc.InnerID))
{
Add(计算,新列表{propValue});
}
其他的
{
(lookUpForResult[calc.InnerID]).Add(propValue);
}

如果不更改
结果的类型,这将不起作用。请将读取器!=null比较放在while子句之外。现在您正在检查它大约60000个…当您可以检查它一次时。是的,我修复了它,这是一个错误:)。谢谢!是的,只存储innerID要快得多,但我以后需要整个计算:(.谢谢你的答案很有用!你能给我看一下我的新答案吗?谢谢你的答案!最后,我解决了它,不使用整个计算器,所以我使用你答案的第一个版本:)。如果我只是重写equal,然后再次使用整个calc,这不是很慢吗?它与我原来的解决方案几乎相同:result.Keys.FirstOrDefault(r=>r.InnerID==calc.InnerID)?@Zoltan:不,这根本不是同一个解决方案。使用FirstOrDefault对所有键执行线性扫描。使用普通字典方法会快得多,因为它将使用哈希表这一事实。我认为它至少使用对数扫描,但你是对的,哈希更快!谢谢!查找的重点是它为您完成了所有这些。您不需要自己添加值。这也应该是对您的问题的编辑…它不是您问题的答案。我无法从查找中找到列表:(.我解决了它,不使用整个计算。感谢您的答案!
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);
}
  tmpElementOfResult = result.Keys.FirstOrDefault(r => r.InnerID == calc.InnerID);
  result.ContainsKey(calc.InnerId);
                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);
                }