views:

67

answers:

3

part of the code:

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

Could you give me some idea how to make it faster, because now it's approximately 25 sec :( ?

+2  A: 

It sounds like you should have a dictionary from the type of calc.InnerID, instead of a Dictionary<Calc, ...>. That way you can do the lookup far more quickly. Do you actually need to store the Calc itself at all, or are you only interested in the ID?

For example:

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

Alternatively, if you can convert the reader to an IEnumerable<Calc> you could use:

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

EDIT: It sounds like two Calc values should be deemed equal if they have the same InnerID, right? So override Equals and GetHashCode within Calc to refer to the InnerID. Then you can just use:

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

... or you can use code like the first snippet, but with a 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);
}
Jon Skeet
Yes, it's far more quickly to store only the innerID, but I need the whole calc later :( .Thanks for the answer it's useful! Could you give my new answer a look?
Zoltán Barna
@Zoltan: Edited.
Jon Skeet
Thanks for the answer!Finally, I solved it not to use the whole calc, so I use the first version of your answer :) .Won't it be slow if I just override the equal, and use the whole calc again? Isn't it almost the same solution like my original:result.Keys.FirstOrDefault(r => r.InnerID == calc.InnerID); ?
Zoltán Barna
@Zoltan: No, it's not the same solution at all. Using FirstOrDefault performs a linear scan of all the keys. Using the normal dictionary methods will be *much* quicker because it'll use the fact that it's a hash table.
Jon Skeet
I thought that it uses at least logarithmic scan, but you're right hashing is much quicker! Thanks!
Zoltán Barna
A: 

instead of

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

use

  result.ContainsKey(calc.InnerId);

to check if a key is present.

schoetbi
That's not going to work without changing the type of `result`.
Jon Skeet
A: 

Is it possible to do something like this:

                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);
                }
Zoltán Barna
The point of the lookup is that it does all of that for you. You don't need to add the values yourself. This should also be an edit to your question... it's not an *answer* to your question.
Jon Skeet
I can't reach the List<PropertyValue> from the LookUp :( .
Zoltán Barna
I solved it not to use the whole calculation. Thanks for the answers!
Zoltán Barna