使用条目字段作为键的字典数据结构

时间:2014-01-10 10:09:48

标签: oop data-structures dictionary d

某种类型的数据记录经常必须用唯一键索引。通常它看起来像这样(我使用的是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关键字不能保证它。

所以,我有几个问题:

  1. 这是一个真正的问题吗?我所拥有的第一个解决方案的缺点在某种程度上是理论上的 - 毕竟可能没有任何问题。
  2. 有什么其他可能的解决方法?
  3. 建议的解决方案有哪些其他可能的缺点?

2 个答案:

答案 0 :(得分:1)

1。)我不这么认为。

2。)使用带有键和值的结构,我不认为lambdas是必要的

3.。)性能问题(缓存未命中)

答案 1 :(得分:1)

1 - 在值得担心的地方,开销不够高。由于字符串是引用类型且不可变,因此您不存储两个字符串,只是对同一字符串(或任何其他键)的附加引用。

当然,您可以编写字典,这样您就不会单独存储键和值,而只会存储值(然后在该对象中查找键)。但是,最多你要保存(PtrSize(4或8字节)*支持数组的大小)),这通常应该很小。另外,当你转到存储的对象以找到查找键值的位置(可能在内存中的其他位置)时,你可能会获得间接,导致缓存未命中。

如果你想翻阅自己的字典来做这件事,请查看这本免费的电子书:

http://www.syncfusion.com/resources/techportal/ebooks/datastructurespart2

他们经历了如何散列这个,所以它应该很容易。或者,您只需从单一项目源代码中复制。