0

I have KeyValuePairs and i want to add the new value to a ConcurrentDictonary. If the key is not contained i want to add it. But what is faster/better:

this:

dict.AddOrUpdate(pair.Key, pair.Value, (ok, ov) => pair.Value);

or this:

if (dict.ContainsKey(pair.Key))
{
    dict[pair.Key] = pair.Value;
}
else
{
    dict.TryAdd(pair.Key, pair.Value);
}

I am concerned that the AddOrUpdate does additional work that i don't want/need and that it takes longer because the Lambda has to be executed too.

Which of those two methods is faster? Or is there a even faster Method?

1 Answers1

2

AddOrUpdate in concurrent dictionary is atomic operation, if you separate that to two method calls ContainsKey and TryAdd its no longer atomic and so defeats the purpose of concurrent dictionary. You should not worry about performance in this case.

I am concerned that the AddOrUpdate does additional work that i don't want/need

The two codes are not equivalent. if you want thread safety use AddOrUpdate. if thread safety is not issue, then just use Dictionary which is simpler and faster than ConcurrentDictionary

and that it takes longer because the Lambda has to be executed too.

executing lambdas are as fast as executing other methods (if you don't fall into micro optimizing ofcourse)

M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • in my case i would need to override the AddOrUpdate to add additional code. Same goes for the TryAdd. So no matter which method i use those functions aren't atomic anymore. but the additional code should have no inpact on thread safety. – MidnightCommander Mar 05 '19 at 15:03
  • Can i use the ContainsKey and the TryAdd and still be threadsafe? for example by locking the ConcurrentDictionary? – MidnightCommander Mar 05 '19 at 15:08
  • does this add the KeyValuePair if it is not already in the ConcurrentDictonary? – MidnightCommander Mar 05 '19 at 15:22
  • @MidnightCommander sorry, don't use indexer. it wont be thread safe. see https://stackoverflow.com/questions/17926519/concurrent-dictionary-addorupdate-vs-index-add specifically this answer https://stackoverflow.com/a/17926706/4767498 – M.kazem Akhgary Mar 05 '19 at 15:26
  • I'm not so good at english. So adding something unconditionally means that it's not thread safe. Did i get that right? Or what does "unconditionally" mean in this context? @M.kazem Akhgary – MidnightCommander Mar 05 '19 at 15:34
  • it's thread safe, but if `dict[key] = value` fails , it wont try again. but `AddOrUpdate` tries until it successfully add or update. @MidnightCommander – M.kazem Akhgary Mar 05 '19 at 16:18
  • thank you, that already helps me. And what does it mean to store something unconditionally? – MidnightCommander Mar 05 '19 at 16:35
  • if you are referring to that comment, by "unconditionally" he meant "without the while loop". if you look at the code showed here https://stackoverflow.com/a/17926706/4767498 you will see that `AddOrUpdate` uses a while loop until it can successfully do add or update. but `dict[key] = value` (the first code) only calls TryAddInternal once, without the while loop (unconditionally). @MidnightCommander – M.kazem Akhgary Mar 06 '19 at 05:46
  • You may want to use the indexer. now that i think about it, i would use indexer myself. https://stackoverflow.com/a/23961609/4767498 @MidnightCommander – M.kazem Akhgary Mar 06 '19 at 05:51