2009-10-14 4 views
0

Je rencontre des problèmes de performances lorsque je compile pour remplir une liste tapée. Ci-dessous est mon code simplifié:Liste <T> performance de collecte de remplissage

  public static List<Product> GetProducts() 
     { 
     List<Product> products = new List<Product>();    
     using (DbQuery query = new DbQuery()) //this is database access class 
     { 

      query.CommandText = "SELECT ProdID, ProdName,Price FROM SomeTable " ;+ 

      using (IDataReader rdr = query.ExecuteReader()) 
      { 
       while (rdr.Read()) 
       { 
        Product prd = new Product(); 
        prd.ProdID = DbQuery.ReadInt (rdr, "ProdID", -1); 
        prd.ProdName = DbQuery.ReadString(rdr, "ProdName", ""); 
        prd.Price = DbQuery.ReadDouble(rdr, "Price", 0); 
        products.Add(prd); 
       } 
      } 
     } 
     } 

J'ai également struct simple Product (ProdID, ProdName, Price).

mon problème est que cela prend 4 secondes pour exécuter GetProducts(). La requête retourne environ 600 enregistrements et il faut des millisecondes pour retourner le résultat, donc je suis sûr que le remplissage de la collection de produits prend tout ce temps. Est-ce que je fais quelque chose d'inefficace ici? S'il vous plaît, aidez. Merci, Gerda

Répondre

1

Avez-vous essayé de mettre un index sur les champs que vous filtrez? Cela va certainement accélérer vos requêtes par rapport à ne pas avoir d'indices.

1

L'insertion de la liste est très rapide. Quelque chose d'autre doit se passer ici. Essayez de le chronométrer avec et sans products.Add(prd) commenté. Je pense que vous trouverez qu'ils sont presque identiques.

Voici comment je résoudrais ceci: commentez une ligne à la fois jusqu'à ce que vous voyiez un grand saut dans la performance - alors vous aurez trouvé votre coupable. Autre chose à surveiller: les performances de la base de données ne sont pas statiques.

Par exemple, une requête qui prend 4 secondes pour s'exécuter une première fois ne prend que 100 msec pour s'exécuter une seconde fois, car toutes les données sont mises en cache dans la RAM, donc aucune E/S physique ne doit être effectuée la deuxième fois. Et la toute première requête sur une base de données sera lente, car SQL génère beaucoup de choses. Ma suggestion: commencez toujours par un cache chaud, c'est-à-dire exécutez le code une fois, puis exécutez-le à nouveau, et ne considérez que le second timing réel. Encore mieux, exécutez le code 10 fois, puis chronométrez-le 10 fois, et jetez les 10 premiers et faites la moyenne de la seconde.

0

Je serais surpris si c'est votre goulot d'étranglement. Je voudrais essayer de faire une petite application de test qui a une connexion de base de données fictive.

Vous pouvez généralement faire un peu mieux si vous pouvez pré-dimensionner la liste. S'il y a une taille minimale raisonnable pour la requête, ou si vous avez une autre façon de savoir (ou de deviner raisonnablement) une bonne taille initiale, vous pourriez obtenir un petit coup de pouce.

0

Juste des sons de celui-ci, cela doit être une performance de base de données ou problème de latence (en cas de connexion à distance.)

1

Comme Justin recommande, je personnellement commencer à commenter les sections de code jusqu'à ce que j'ai trouvé ce qui était à l'origine le goulot d'étranglement. Par exemple, je pourrais commencer par faire la routine exécuter uniquement le code de base de données centrée sur:

public static List<Product> GetProducts() 
     { 
      List<Product> products = new List<Product>(); 

      using (DbQuery query = new DbQuery()) 
      { 
       query.CommandText = "SELECT ProdID, ProdName,Price FROM SomeTable "; 

       using (IDataReader rdr = query.ExecuteReader()) 
       { 
        while (rdr.Read()) 
        { 
         //Product prd = new Product(); 
         //prd.ProdID = DbQuery.ReadInt(rdr, "ProdID", -1); 
         //prd.ProdName = DbQuery.ReadString(rdr, "ProdName", ""); 
         //prd.Price = DbQuery.ReadDouble(rdr, "Price", 0); 
         //products.Add(prd); 
        } 
       } 
      } 

      return products; 
     } 

En commentant la section qui crée les objets du produit et les ajoute à la liste, je peux voir à quelle vitesse la base de données connexes le code s'exécute. Si cela dure plus de 4 secondes, je sais que cela a quelque chose à voir avec la création de l'objet Product et/ou les appels à DBQuery qui prennent beaucoup de temps. C'est un essai et une erreur, mais comme cette routine est très simple, il ne faut pas longtemps pour faire ce type d'analyse.

Questions connexes