2010-10-23 3 views
1

Préambule: Je travaille sur une application lourdement chargée qui produit de grandes baies de données.Qu'est-ce qui est le plus rapide et le plus pratique: Hashtable ou Dictionary <int, double>()?

j'ai écrit la classe suivante

using System; 
    using System.Collections; 
    using System.Collections.Generic; 

    namespace CSharpSampleApplication.Data.CoreObjects 
    { 
     [Serializable] 
     public class CalcItem 
     { 
      public CalcItem() 
      { 
       _additional = new Hashtable(); 
      } 

      private readonly Hashtable _additional; 

      public bool ContainsKey(int id) 
      { 
       return _additional.ContainsKey(id); 
      } 

      public void Add(int id, double value) 
      { 
       _additional.Add(id, value); 
      } 

      public DateTime Date { get; set; } 

      public object this[int id] 
      { 
       get 
       { 
        return _additional[id]; 
       } 
      } 
     } 


    } 

Puis, dans une autre classe, je l'ai fait gestionnaire qui contient les éléments suivants:

public List<CalcItem> CalcItems{ get; private set;} 
    private readonly Dictionary<string, int> _keys; 
    private int _index; 
    private readonly object _lock = new object(); 

    public int GetIndex(string key) 
    { 
     lock (_lock) 
     { 
      if (_keys.ContainsKey(key)) 
       return _keys[key]; 
      else 
      { 
       _index++; 
       _keys.Add(key, _index); 
       return _index; 
      } 
     } 
    } 

En utilisant ces classes i Enregistre des données en temps réel, par exemple comme this:

   var clc = new CalcItem(); 
       clc.Date = DateTime.Now; 
       clc.Add(_calcItemManager.GetIndex("testData"), r.Next()/100.00); 
       clc.Add(_calcItemManager.GetIndex("testData1"), r.Next()/100.00); 

       i++; 

       if (i % 25 == 0) 
       { 
        clc.Add(_calcItemManager.GetIndex("testData2"), r.Next()/100.00); 
        clc.Add(_calcItemManager.GetIndex("testData3"), r.Next()/100.00); 
        clc.Add(_calcItemManager.GetIndex("testData4"), r.Next()/100.00); 
        clc.Add(_calcItemManager.GetIndex("testData5"), r.Next()/100.00); 
       } 
       _calcItemManager.Add(clc); 

Ainsi, le gestionnaire stocke les liaisons [chaîne de clé] - [index int] pour tous les calcItems.

La question est: Est-il préférable d'utiliser Dictionary<int, double> au lieu de Hashtable() pour optimiser l'utilisation de la mémoire et une performance plus rapide? Liste des articles - contient environ 1.000.000 enregistrements CalcItem.Additional - contient environ 5 - 10 dossiers

Répondre

5

La façon obly de répondre « plus vite » est de temps pour vos données typiques. Cependant, le dictionnaire est plus pratique (pas besoin de lancer) et efficace (pas de boxe). Si les clés de données sont contiguës, il serait préférable d'utiliser un List-of-double et d'utiliser la clé comme index (avec décalage si vos données ne commencent pas à 0).

+0

Le meilleur! Liste-de-double - idée incroyable - voir ma réponse et la nouvelle classe CalcItem !!! Merci beaucoup. – skaeff

1

Je pense que la réponse acceptée à this StackOverflow question répond également à votre question.

En bref, les deux structures de données auront des performances très similaires dans la plupart des situations. Si c'est important pour vous, vous pouvez (et devriez) mesurer.

0

Marc Gravell - une décision incroyable avec List-of-double !!! Comment pourrais-je manquer ça ?! Mémoire réduite deux fois! Voici mon nouveau code:

using System; 
    using System.Collections; 
    using System.Collections.Generic; 

    namespace CSharpSampleApplication.Data.CoreObjects 
    { 
     [Serializable] 
     public class CalcItem 
     { 
      public CalcItem() 
      { 
       _additional = new List<double>(); 
      } 

      private readonly List<double> _additional; 

      public bool ContainsKey(int id) 
      { 
       return _additional.Count - 1 >= id; 
      } 

      public void Add(int id, double value) 
      { 
       if(ContainsKey(id)) 
        _additional[id] = value; 
       else 
       { 
        while (!ContainsKey(id)) 
        { 
         _additional.Add(0); 
        } 
        _additional[id] = value; 
       } 
      } 

      public DateTime Date { get; set; } 

      public object this[int id] 
      { 
       get 
       { 
        return _additional[id]; 
       } 
      } 
     } 


    } 
Questions connexes