повышение производительности firstorDefault - PullRequest
1 голос
/ 25 августа 2010

часть кода:

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 ]

2 голосов
/ 25 августа 2010

Похоже, у вас должен быть словарь типа calc.InnerID вместо Dictionary<Calc, ...>. Таким образом, вы можете сделать поиск гораздо быстрее. Вам вообще нужно хранить сам Calc или вас интересует только идентификатор?

Например:

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

РЕДАКТИРОВАТЬ: звучит так, что два значения Calc должны считаться равными, если они имеют одинаковые InnerID, верно? Поэтому переопределите Equals и GetHashCode внутри Calc, чтобы обратиться к 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);
}
0 голосов
/ 25 августа 2010

Можно ли сделать что-то вроде этого:

                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);
                }
0 голосов
/ 25 августа 2010

вместо

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

используйте

  result.ContainsKey(calc.InnerId);

для проверки наличия ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...