HomeSearch

C# TryGetValue (Get Value From Dictionary)

Use the TryGetValue method on Dictionary to test a key, and get a value.
TryGetValue. This method optimizes Dictionary usage. It gets a value (at a key) from a Dictionary. And it eliminates unneeded lookups, making programs better.ContainsKeyContainsValue
Some notes. 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, example. We can rewrite programs that use ContainsKey with TryGetValue. By combining 2 operations (try and get) into 1, we can optimize and simplify programs.

Important: Every lookup has to compute the hash code, which has a performance penalty. The TryGetValue method can help here.

Value: Look carefully at "value" in this program. It is accessed by TryGetValue, and we do not need to get it again when we use it.

C# program that uses TryGetValue using System; using System.Collections.Generic; class Program { static void Main() { 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"]); } } } Output VALUE: 1
ContainsKey. This example shows an increment on a Dictionary key. Two lookups are done when this occurs—one to get the value, and another to change it.

And: This is inefficient. Unlike the version with TryGetValue, we do an extra lookup to get "value" again.

C# program that uses ContainsKey using System; using System.Collections.Generic; class Program { static void Main() { var counts = new Dictionary<string, int>(); counts.Add("key", 0); // This causes an unneeded look up. if (counts.ContainsKey("key")) { counts["key"]++; Console.WriteLine("VALUE: " + counts["key"]); } } } Output VALUE: 1
ContainsKey, explanation. Here the increment does two lookups when we only need one. To increment the value in the Dictionary, we have to get it.
C# program that shows what ContainsKey does using System; using System.Collections.Generic; class Program { static void Main() { var counts = new Dictionary<string, int>(); counts.Add("key", 0); // This causes extra lookups. if (counts.ContainsKey("key")) { counts["key"] = counts["key"] + 1; Console.WriteLine("VALUE: " + counts["key"]); } } } Output VALUE: 1
Benchmark, TryGetValue. This benchmark compares the TryGetValue method against ContainsKey and indexer. It compares 1 lookup against 2 lookups.

Version 1: Use ContainsKey. If the key exists, access the value again in a separate lookup statement.

Version 2: This version of the code uses TryGetValue, and stores the result value which is then used for the sum.

Result: It is faster to just use the TryGetValue method and access the already-known value from a local variable.

C# program that benchmarks ContainsKey and TryGetValue using System; using System.Collections.Generic; using System.Diagnostics; class Program { const int _max = 10000000; static void Main() { 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")); } } Output 38.11 ns ContainsKey, indexer 21.16 ns TryGetValue
A summary. 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.Dictionary
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls