问题
Preamble: I'm working at heavy-loaded applicaion that produces large data arrays.
I wrote the following class
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];
}
}
}
}
Then, in another class, i made manager which contains the following:
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;
}
}
}
By using those classes i log some realtime data, for example like 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);
So the manager stores [string key]-[int index] bindings for all the calcItems.
The question is:
Is it better to use Dictionary<int, double> instead of Hashtable() to optimize memory usage and faster perfomance?
List Items - contains about 1.000.000 records
CalcItem.Additional - contains about 5 - 10 records
回答1:
The obly way to answer "faster" is to time it for your typical data. However the dictionary is more convenient (no need to cast) and efficient (no boxing).
If the data keys are contiguous, however, it would be better just to use a List-of-double, and use the key as the index (with offset if your data doesn't start at 0).
回答2:
I think the accepted answer to this StackOverflow question also answers your question.
In brief, both data structures will have very similar performance in most situations. If it's important for you, you can (and should) measure.
回答3:
Marc Gravell - awsome decision with List-of-double!!! How could i miss that?! Memory reduced twice! Here is my new 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];
}
}
}
}
来源:https://stackoverflow.com/questions/4003019/what-is-faster-and-more-convenient-hashtable-or-dictionaryint-double