为多个参数创建一个唯一的密钥(缓存密钥)
我有一个基于3个参数缓存数据的方法。例如:为多个参数创建一个唯一的密钥(缓存密钥)
- 状态
- 年龄
- 兄弟姐妹的数量。
现在我有很多在我的系统排列,它们被保存在一个字典:
Dictionary<string,MyObject> cache;
字典的关键是这三者的concatination并与string.format
(像这样)来完成:
public string CreateKey(eState state, int age, int numberOfSibilings)
{
return string.format("{0}#{1}#{2}", state.ToString(), age.ToString(), numberOfSibilings.ToString());
}
eState
是enum(int)
。
CreateKey
方法被调用很多次,是一个性能障碍,因为string.format
不是特别快,创建很多不可变的字符串不是最好的。
密钥可以有空的项目被替换为*
。 CreateKey
方法处理它们,因为它输入空值并检查它们是否有值。
我确定有更好的方法来做到这一点。而且由于eState
是int
,我想过用数学公式快速创建密钥,但我无法想象快速而独特的事情。
无论如何,我愿意为您提供的任何解决方案来创建一个尽可能快速和内存友好的独特密钥。
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.ToString
这涉及拳击(我猜)。我们的MyKey
结构没有任何拳击。这意味着更好的性能。
如果您正在寻找调试友好密钥(在注释中提及),则可以使用DebuggerDisplay
属性。
[DebuggerDisplay("State= {State} Age= {Age}")]
public struct MyKey : IEquatable<MyKey>
你也可以使用一个元组的关键:
Dictionary<Tuple<eState, int, int>, MyObject> dict;
元组评估平等这样的:
- 它是一种
Tuple<T1, T2, T3>
对象 - 它的三个组成部分是与正在比较的元组类型相同
- 每个值都使用默认的
Equals
方法相等。
见https://msdn.microsoft.com/en-us/library/dd387109(v=vs.110).aspx
的好处是,你不必创建一个新的类型来保存你的密钥,它采用了平等comparers不管什么类型是你的元组,并且很容易使用:
var myKey = new Tuple<eState, int, int>(eState.Whatever, 10, 15);
dict.Add(myKey, myObject)
+ 1-谢谢你的答案。这里的问题是很多元组=堆上的大量内存。我更喜欢用数学公式来代替。 –
不知道如何调试密钥不友好,它在调试器中显示为“{(eState.Whatever,10,15)}”。它虽然占用更多的内存,但不一定在堆上。 –
我收回调试器友好的东西。 –
+1 - 谢谢你的回答。我喜欢这种方法。我正在寻找一些简单的数学方法来创建一个键(更容易调试它),我相信有。但这是一个很好的方法,它可能是最终的实现:)。 –
@AmirPopovich你的意思是调试器来帮助你使用可读密钥? –
是的..我不希望从哈希代码和其他东西开始。 –