我需要超级快速存储并通过两个整数键检索值。
所以我输入值为uint Id1, uint Id2
,需要获取uint Count
。
我也知道Id1
和Id2
的最大值(约为5 000 000)。
我目前的实施大约占应用工作时间的70%,可能需要几天时间。
它只使用标准的.net词典,当然可以改进。但我想这是计算机科学中非常有用的操作,毫无疑问存在更有效的算法。
这是我的实施
void Main()
{
var rep = new Repository();
var sw = new Stopwatch();
sw.Start();
for (uint i = 0; i < 10000; i++)
{
for (uint j = 0; j < 1000; j++)
{
rep.Add(new DomainEntity(){Id1 = i, Id2 = j, Count = 1});
}
}
for (uint i = 0; i < 10000; i++)
{
for (uint j = 0; j < 1000; j++)
{
rep.GetDomainEntityByIds(i,j);
}
}
sw.Stop();
Console.WriteLine ("Elapsed:{0}", sw.Elapsed);
}
public class Repository
{
private readonly Dictionary<Tuple<UInt32, UInt32>, UInt32> _dictStore;
public Repository()
{
_dictStore = new Dictionary<Tuple<uint, uint>, uint>();
}
public uint Add(DomainEntity item)
{
var entry = MapToTableEntry(item);
_dictStore.Add(entry.Key,entry.Value);
return 0;
}
public void Update(DomainEntity item)
{
var entry = MapToTableEntry(item);
_dictStore[entry.Key] = entry.Value;
}
public IEnumerable<DomainEntity> GetAllItems()
{
return _dictStore.Select(MapToDomainEntity);
}
public DomainEntity GetDomainEntityByIds(uint articleId1, uint articleId2)
{
var tuple = new Tuple<uint, uint>(articleId1, articleId2);
if (_dictStore.ContainsKey(tuple))
{
return MapToDomainEntity(new KeyValuePair<Tuple<uint, uint>, uint>(tuple, _dictStore[tuple]));
}
return null;
}
private KeyValuePair<Tuple<uint, uint>, uint> MapToTableEntry(DomainEntity item)
{
return new KeyValuePair<Tuple<uint, uint>, uint>(new Tuple<uint, uint>(item.Id1,item.Id2), item.Count);
}
private DomainEntity MapToDomainEntity(KeyValuePair<Tuple<uint, uint>, uint> entry)
{
return new DomainEntity
{
Id1 = entry.Key.Item1,
Id2 = entry.Key.Item2,
Count = entry.Value,
};
}
}
public class DomainEntity
{
public uint Id1 { get; set; }
public uint Id2 { get; set; }
public uint Count { get; set; }
}
答案 0 :(得分:5)
一个小的(?)改进,您可以使用TryGetValue
来避免两次查找字典:
public DomainEntity GetDomainEntityByIds(uint articleId1, uint articleId2)
{
var tuple = new Tuple<uint, uint>(articleId1, articleId2);
uint value;
if (_dictStore.TryGetValue(tuple, out value))
{
return MapToDomainEntity(new KeyValuePair<Tuple<uint, uint>, uint>(tuple, value));
}
return null;
}
答案 1 :(得分:1)
您要做的是使用有效的密钥和密钥创建一个有效的字典。哈希值。由于字典总是使用32位值并且您有大约45位数据,因此您无法创建唯一的哈希值,但您应该尽力而为。
示例:
public class Storage
{
private Dictionary<Key, DomainObject> dict;
public Storage()
{
dict = new Dictionary<Key, DomainObject>(Key.Comparer.Instance)
}
public DomainObject Get(uint a, uint b)
{
DomainObject obj;
dict.TryGetValue(new Key(a,b), out obj);
return obj;
}
internal struct Key
{
internal readonly uint a;
internal readonly uint b;
public Key(uint a, uint b)
{
this.a = a;
this.b = b;
}
internal class Comparer : IEqualityComparer<Key>
{
internal static readonly Comparer Instance = new Comparer();
private Comparer(){}
public bool Equals(Key x, Key y)
{
return x.a == y.a && x.b == y.b;
}
public int GetHashCode(Key x)
{
return (int)((x.a & 0xffff) << 16) | (x.b & 0xffff));
}
}
}
}
答案 2 :(得分:0)
你在那里做了很多额外的工作,转换为KeyValuePair
。此外,DomainEntity
是一种引用类型,因此您可能只应存储对字典中的引用,而不是每次查看时都必须从键和值创建它们。
将您的字典创建为:
var _dictStore = new Dictionary<Tuple<uint, uint>, DomainEntity>();
然后:
public uint Add(DomainEntity item)
{
var key = new Tuple<uint, uint>(item.Id1, item.Id2);
_dictStore.Add(key, item);
return 0;
}
查找:
public DomainEntity GetDomainEntityByIds(uint articleId1, uint articleId2)
{
var key = new Tuple<uint, uint>(articleId1, articleId2);
DomainEntity value;
if (!_dictStore.TryGetValue(key, out value))
{
value = null;
}
return value;
}