Daily Knowledge Drop
A Dictionary
record can be destructed into a Tuple
- specifically the KeyValuePair
type representing a dictionary record can be destructed into a Tuple
. In addition, as the Dictionary
type contains a GetEnumerator method, it can be iterated over into a Tuple
.
Examples
In all of the below examples, numberDictionary is of type Dictionary<string, int>
.
Key iteration
One way to iterate through all entries in a Dictionary
is to loop through each Key
and then use the Key to retrieve the entry Value
.
public void IterateKeyValue()
{
var sum = 0;
// iterate of each key in the dictionary
foreach (var key in numberDictionary.Keys)
{
// get the int value based on the key
sum += numberDictionary[key];
}
}
Here the Dictionary
is accessed twice, once to get the Key and a second time to get the Value for the specific Key.
KeyValue iteration
The next method for iteration, is to iterate through each Dictionary
record, a KeyValuePair
. This is possible because Dictionary contains a GetEnumerator method.
public void IterateKVPair()
{
var sum = 0;
// iterate of each KeyValuePair in the dictionary
foreach (KeyValuePair<string, int> kv in numberDictionary)
{
// get the value part of the KeyValuePair
sum += kv.Value;
}
}
Simpler than the previous method, and here the Dictionary itself is only accessed only once to get the KeyValuePair
which in turn contains all the information for the entry.
Tuple
The last method for iteration, is to iterate through each Dictionary
item, but destruct the KeyValuePair into a Tuple
.
public void IterateTuple()
{
var sum = 0;
// iterate and destruct into a tuple
foreach (var (key, value) in numberDictionary)
{
// access the value directly
sum += value;
}
}
One could argue whether this version is easier to read than the previous KeyValuePair version - personally I do find this version more readable. An added benefit is that the name of the Tuple
items can be customized to make it obvious to the reader as to what they contains. So instead of Key and Value:
public void IterateProducts()
{
var sum = 0;
foreach (var (productName, price) in productDictionary)
{
sum += intValue;
}
}
Benchmarks
So we've looked at three ways to get the information from a Dictionary, but how to each of them perform?
Method | Mean | Error | StdDev | Ratio |
---|---|---|---|---|
IterateKeyValue | 14.827 us | 0.1774 us | 0.1659 us | 1.00 |
IterateTuple | 3.529 us | 0.0468 us | 0.0438 us | 0.24 |
IterateKVPair | 3.519 us | 0.0296 us | 0.0262 us | 0.24 |
The KeyValuePair
and Tuple
versions are comparable, while iterating through each Key and then getting the Value is 4 times slower
.
Notes
Iterating through Keys, to then retrieve the Value shouldn't ever be the default method for iteration - especially when there are other more performant and easier to read methods available.
KeyValuePair and Tuple iteration are comparable, and usage comes down to personal preference - personally I prefer the Tuple
with its added benefit of being able to accurately name the Key and Value.
References
Daily Drop 105: 28-06-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.