我有一种基于3个参数缓存数据的方法。例如:
现在我的系统中有很多排列,它们保存在字典中:
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());
}
eState
是enum(int)
。
CreateKey
方法被多次调用并且是一个性能障碍,因为string.format
不是特别快,并且创建大量不可变字符串并不是最好的。
密钥可以包含由*
替换的空条目。 CreateKey
方法处理它们,因为它输入了nullables并检查它们是否有值。
我确信有更好的方法可以做到这一点。由于eState
是一个int
,我想用数学公式以更快的方式创建一个键,但我无法想到快速而独特的东西。
无论如何,我愿意为您创建一个尽可能快速且对内存友好的唯一密钥提供任何解决方案。
答案 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)