如果是字典,其中键是复杂的(值的组合) 例如,密钥可以是一对字符串和整数。
您建议将哪种数据类型用于密钥?我考虑了字典中大量读取时的性能和内存使用情况,分配繁重的数据类型可能不适合该任务。
我测试了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];
}
我不喜欢第一种方法,带元组的那种方法看起来更优雅。 但是,Tuple与字符串没有那么不同,因为它们都是类,分配它们可能很昂贵。 KeyValuePair似乎是最可行的数据类型,但在运行一些测试后,我发现它的性能比字符串或元组差得多,现在看来KeyValuePair没有实现GetHashCode()。 然后我尝试实现我自己的“KeyValuePair”,它覆盖了Equals和GetHashCode():
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通常会处理这个问题。
答案 0 :(得分:1)
我更喜欢使用具有相关属性名称的特定类型:
public class RowKey
{
public string Title { get; set; }
public int Id { get; set; }
public RowKey()
{
}
public RowKey(string title, int id)
{
Title = title;
Id = id;
}
public override bool Equals(object obj)
{
if (!(obj is RowKey))
return false;
RowKey other = obj as RowKey;
return Title.Equals(other.Title) && Id.Equals(other.Id);
}
public override int GetHashCode()
{
int titleHash = Title.GetHashCode();
int idHash = Id.GetHashCode();
return (((titleHash << 5) + titleHash) ^ idHash);
}
}
阅读使用:
int Read(string str, int num)
{
var key = new RowKey(str, num);
return dict[key];
}