为多个参数创建唯一键(缓存键)

时间:2015-05-05 15:36:16

标签: c# .net caching

我有一种基于3个参数缓存数据的方法。例如:

  1. 状态
  2. 年龄
  3. 兄弟姐妹的数量。
  4. 现在我的系统中有很多排列,它们保存在字典中:

    Dictionary<string,MyObject> cache;
    

    字典的关键是三者的连接,用string.format完成(类似这样):

    public string CreateKey(eState state, int age, int numberOfSibilings)
    {
        return string.format("{0}#{1}#{2}", state.ToString(), age.ToString(), numberOfSibilings.ToString());
    }
    

    eStateenum(int)

    CreateKey方法被多次调用并且是一个性能障碍,因为string.format不是特别快,并且创建大量不可变字符串并不是最好的。

    密钥可以包含由*替换的空条目。 CreateKey方法处理它们,因为它输入了nullables并检查它们是否有值。

    我确信有更好的方法可以做到这一点。由于eState是一个int,我想用数学公式以更快的方式创建一个键,但我无法想到快速而独特的东西。

    无论如何,我愿意为您创建一个尽可能快速且对内存友好的唯一密钥提供任何解决方案。

2 个答案:

答案 0 :(得分:3)

当代码性能至关重要时,

string.format并不是那么好。它将参数作为Object类型,这意味着您需要将int和其他值类型包装起来。

您可以创建一个自定义结构,可用作词典的键。您需要在结构中实现IEquatable<MyKey>,以便在调用Equals方法时不需要加框。

public struct MyKey : IEquatable<MyKey>
{
    public readonly eState State;
    public readonly int Age;
    public readonly int NumberOfSibilings;

   ...Implement Equals method here
}

然后使用

Dictionary<MyKey ,MyObject> cache;
public MyKey CreateKey(eState state, int age, int numberOfSibilings)
{
    return new MyKey(state, age, numberOfSibilings);
}

这样您就不必在CreateKey方法中创建多个字符串。没有转换;你只需将它们存储为int和enum本身。没有调用涉及拳击的Enum.ToString(我猜)。我们的MyKey结构没有任何拳击。这意味着更好的表现。

如果您正在寻找调试器友好密钥(在评论中提到),您可以使用DebuggerDisplay属性。

[DebuggerDisplay("State= {State} Age= {Age}")]
public struct MyKey : IEquatable<MyKey>

答案 1 :(得分:1)

你也可以使用元组作为你的钥匙:

Dictionary<Tuple<eState, int, int>, MyObject> dict;

Tuple像这样评估相等:

  • 它是Tuple<T1, T2, T3>对象
  • 它的三个组件与被比较的元组的类型相同
  • 使用默认的Equals方法,每个值都相等。

请参阅https://msdn.microsoft.com/en-us/library/dd387109(v=vs.110).aspx

优点是您不必创建一个新类型来保存您的密钥,它使用等式比较器来处理您的元组中的任何类型,并且易于使用:

var myKey = new Tuple<eState, int, int>(eState.Whatever, 10, 15);
dict.Add(myKey, myObject)