【发布时间】:2017-04-06 15:59:45
【问题描述】:
如果字典的键很复杂(值的组合) 例如,键可以是一对字符串和整数。
您建议使用什么数据类型作为密钥?如果从字典中进行大量读取,我会考虑性能和内存使用情况,分配繁重的数据类型可能不适合该任务。
我测试了 4 种不同的策略。
-
最幼稚的一种,使用字符串作为键并连接组件:
int Read(string str, int num) { var key = str + "|" + num; return dict[key]; } -
使用元组表示键:
int Read(string str, int num) { var key = new Tuple<string, int>(str, num); return dict[key]; } -
使用 KeyValuePair 表示键:
int Read(string str, int num) { var key = new KeyValuePair<string, int>(str, num); return dict[key]; }
我不太喜欢第一种方法,带有元组的方法看起来更优雅。 然而,元组与字符串并没有太大区别,因为它们都是类并且分配它们可能很昂贵。 KeyValuePair 似乎是最可行的数据类型,但在运行了一些测试后,我发现它的性能比字符串或元组差得多,鉴于 KeyValuePair 没有实现 GetHashCode(),这对我来说现在似乎很明显。 然后我尝试实现我自己的覆盖 Equals 和 GetHashCode() 的“KeyValuePair”:
struct KVPair<K, V>
{
public K Key { get; set; }
public V Value { get; set; }
public KVPair(K key, V value)
{
Key = key;
Value = value;
}
public override bool Equals(object obj)
{
if (!(obj is KVPair<K,V>))
{
return false;
}
KVPair<K, V> other = (KVPair<K, V>)obj;
return Key.Equals(other.Key) &&
Value.Equals(other.Value);
}
public override int GetHashCode()
{
int keyHash = Key.GetHashCode();
int valHash = Value.GetHashCode();
return (((keyHash << 5) + keyHash) ^ valHash);
}
}
并将其用作我字典中的键:
int Read(string str, int num)
{
var key = new KVPair<string, int>(str, num);
return dict[key];
}
它似乎比字符串和元组选项表现得更好,比原生的 KeyValuePair 好得多。
我只是想听听你会推荐什么。 在必须实现自己的数据类型时,我总是很谨慎,因为 FCL 通常会处理这个问题。
【问题讨论】:
标签: c# .net dictionary tuples