如何使用单个键查找优化更新c#字典?

时间:2014-01-29 07:28:31

标签: c# optimization dictionary

比如说我有

Dictionary<string, double> foo;

我能做到

foo["hello"] = foo["hello"] + 2.0

或者我能做到

foo["hello"] += 2.0

但编译器只是将其扩展为上面的代码。我通过使用JetBrains验证了.Pek来查看程序集。

这似乎很浪费,因为需要更新两个关键查找。是否有一个字典实现可以在一次查找中执行此操作?注意我正在使用字典来存储来自网格的100k项几何信息,并且查找位于内部循环中。请不要"premature optimization is the root of all evil"个答案。 :)

是的,我有个人资料。

enter image description here

3 个答案:

答案 0 :(得分:2)

评论中提到的使用类可能会更快,因为:

使用结构,您必须按照注释中的说明进行双重查找。

使用类,您只需转到类引用的内存并在那里更新它。

每次查询:

  • 的GetHashCode
  • 获取存储桶
  • 迭代找到合适的
  • (这都涉及读取多个ref对象值)

但是,如果您使用类并更新其值:

  • 更改相对于该参考的正确位置的值。

这是记忆中的一个变化。

@George Duckett的解决方案应该快得多。更改为类并获取ref并更新对象的值:

var hello = foo["hello"]; 
hello.howAreYou += 2.0;

顺便说一句,这是一个示例,其中一个可变类将在不可变结构上获得性能。

答案 1 :(得分:1)

ConcurrentDictionary中有一个方法,ConcurrentDictionary.AddOrUpdate,可以满足您的需求。您可以一次性根据以前的值更新字典中的现有值。

但是,并发字典应该在多线程情况下使用,所以我可以想象它会做一些锁定,这可能会破坏你的优化目标。但话说回来,你可以随时进行基准测试,看看它是如何发展的。

答案 2 :(得分:1)

不,不是。正如bradgonesurfing的评论中所指出的,该语言缺少一种返回对存储值的引用的方法,因此当它必须更改该值时,它需要再次找到它。

另外,你说你正在存储整数对。你有没有想过使用阵列?甚至100k长的阵列甚至不到1MB大。而且我相信你能获得最快的速度。