2010-08-25 6 views
1

partie du code:performance FirstOrDefault hausse

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

Pourriez-vous me donner une idée comment le rendre plus rapide, parce que maintenant il est environ 25 sec :(

+0

Mettre le lecteur = comparation nulle en dehors de la clause while. Maintenant, vous vérifiez à environ 60000 ... quand vous pourriez le vérifier une fois. – Jonathan

+0

Oui, je le répare, c'est une erreur :). Merci! –

Répondre

2

Il semble que vous devriez avoir un? dictionnaire du type de calc.InnerID, au lieu d'un Dictionary<Calc, ...>. de cette façon, vous pouvez faire la recherche beaucoup plus rapidement. Est-ce que vous avez réellement besoin de stocker le Calc lui-même du tout, ou êtes-vous seulement intéressé par l'ID?

Par exemple :

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

Alternativement, si vous pouvez convertir le lecteur à un IEnumerable<Calc> vous pouvez utiliser:

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

EDIT: Il semble que deux valeurs Calc doivent être considérées comme égales si elles ont le même InnerID, non? Remplacez donc Equals et GetHashCode par Calc pour faire référence au InnerID. Ensuite, vous pouvez simplement utiliser:

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

... ou vous pouvez utiliser le code comme le premier extrait, mais avec un 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

Oui, il est beaucoup plus rapide de stocker seulement l'innerID, mais j'ai besoin de toute la calc plus tard :( Merci pour la réponse, c'est utile! Pouvez-vous donner une réponse à ma nouvelle réponse? –

+0

@Zoltan: Edited. –

+0

Merci pour la réponse! Enfin, je l'ai résolu de ne pas utiliser le calc entier, donc j'utilise la première version de votre réponse :). Est-ce que ce ne sera pas lent si je remplace juste l'égal, et réutilise tout le calc? N'est-ce pas presque la même solution que mon original: résultat.Keys.FirstOrDefault (r => r.InnerID == calc.InnerID); ? –

0

au lieu de

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

utilisation

result.ContainsKey(calc.InnerId); 

pour vérifier si un la clé est présente.

+0

Cela ne va pas fonctionner sans changer le type de 'résultat'. –

0

Est-il possible de faire quelque chose comme ceci:

   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

Le but de la recherche est de faire tout cela pour vous. Vous n'avez pas besoin d'ajouter les valeurs vous-même. Cela devrait aussi être une modification à votre question ... ce n'est pas une * réponse * à votre question. –

+0

Je ne peux pas atteindre la liste à partir du LookUp :(. –

+0

Je l'ai résolu de ne pas utiliser le calcul entier. Merci pour les réponses! –