TryGetValue
This method optimizes Dictionary
usage. It gets a value (at a key) from a Dictionary
. And it eliminates unneeded lookups, making programs better.
With TryGetValue
, we can combine the "try" part of seeing if a key exists, and the "get" part of getting the existing value. This saves 1 lookup.
TryGetValue
, exampleWe can rewrite programs that use ContainsKey
with TryGetValue
. By combining 2 operations (try and get) into 1, we can optimize and simplify programs.
TryGetValue
method can help here.TryGetValue
, and we do not need to get it again when we use it.using System; using System.Collections.Generic; var counts = new Dictionary<string, int>(); counts.Add("key", 0); // Keep the result of TryGetValue. int value; if (counts.TryGetValue("key", out value)) { counts["key"] = value + 1; Console.WriteLine("VALUE: " + counts["key"]); }VALUE: 1
The second argument to TryGetValue
is an out parameter. We can specify the type (here it is bool
) directly in the call to the TryGetValue
method.
using System; using System.Collections.Generic; var ids = new Dictionary<string, bool>() { { "X1", true } }; // We can specify the "out" type by argument. if (ids.TryGetValue("X1", out bool result)) { Console.WriteLine($"VALUE: {result}"); }VALUE: True
TryGetValue
This benchmark compares the TryGetValue
method against ContainsKey
and indexer. It compares 1 lookup against 2 lookups.
ContainsKey
. If the key exists, access the value again in a separate lookup statement.TryGetValue
, and stores the result value which is then used for the sum.TryGetValue
method and access the already-known value from a local variable.using System; using System.Collections.Generic; using System.Diagnostics; const int _max = 10000000; var test = new Dictionary<string, int>(); test["key"] = 1; int sum = 0; // Version 1: use ContainsKey and access the key again for its value. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (test.ContainsKey("key")) { sum += test["key"]; } } s1.Stop(); // Version 2: use TryGetValue and use the key already accessed. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (test.TryGetValue("key", out int result)) { sum += result; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));38.11 ns ContainsKey, indexer 21.16 ns TryGetValue
We can rewrite Dictionary
code to use TryGetValue
instead of ContainsKey
. It is good to avoid the increment or decrement operators here. Instead store the value with TryGetValue
.