某种类型的数据记录经常必须用唯一键索引。通常它看起来像这样(我使用的是C#,因为它是我最熟悉的语言,但这个问题并不是特定的):
public class NamedRecord
{
public readonly string UniqueImmutableName;
...
}
public class UsesUsualDict
{
Dictionary<string, NamedRecord> myDict = new Dictionary<string, NamedRecord>();
void AddRecord(NamedRecord _NewRecord)
{
myDict[_NewRecord.UniqueImmutableName] = _NewRecord;
}
NamedRecord GetRecord(string _Key)
{
return myDict[_Key];
}
}
然而,这似乎有点多余:该词典中的键应始终被视为等于NamedRecord.UniqueImmutableName
,但开发人员自己也会维持这种关系。此外,这种数据重复对我来说感觉不对。
有时候我会看到类似的解决方案:数据记录甚至没有UniqueImmutableName作为其成员。例如,在他的tutorial for D language中,Andrei Alexandrescu使用数据结构来描述游戏中角色的统计数据:
struct PersonaData {
uint totalWordsSpoken;
uint[string] wordCount;
}
但是角色的名字甚至不在其中 - 它只能作为词典的一个关键字来保存这些结构。在这种情境之外,这种数据结构几乎没用。
我想做的是这样的事情:
public class UsesLambdaDict
{
LambdaDictionary<string, NamedRecord> myDict = new LambdaDictionary<string, NamedRecord>(NamedRecord _Record => _Record.UniqueImmutableName);
void AddRecord(NamedRecord _NewRecord)
{
myDict.Add(_NewRecord);
}
NamedRecord GetRecord(string _Key)
{
return myDict[_Key];
}
}
在我看来,这种处理此类数据记录的方式更好,因为NamedRecord的UniqueImmutableName成员与其保存的字典之间的关系在编译时正式化。我看到的缺点是,没有办法确保给定的lambda将是一个纯函数,至少在C#中是这样。我真的不太了解D,但似乎pure
关键字不能保证它。
所以,我有几个问题:
答案 0 :(得分:1)
1。)我不这么认为。
2。)使用带有键和值的结构,我不认为lambdas是必要的
3.。)性能问题(缓存未命中)
答案 1 :(得分:1)
1 - 在值得担心的地方,开销不够高。由于字符串是引用类型且不可变,因此您不存储两个字符串,只是对同一字符串(或任何其他键)的附加引用。
当然,您可以编写字典,这样您就不会单独存储键和值,而只会存储值(然后在该对象中查找键)。但是,最多你要保存(PtrSize(4或8字节)*支持数组的大小)),这通常应该很小。另外,当你转到存储的对象以找到查找键值的位置(可能在内存中的其他位置)时,你可能会获得间接,导致缓存未命中。
如果你想翻阅自己的字典来做这件事,请查看这本免费的电子书:
http://www.syncfusion.com/resources/techportal/ebooks/datastructurespart2
他们经历了如何散列这个,所以它应该很容易。或者,您只需从单一项目源代码中复制。