0

I wonder what is better from performance side? I have big data that I work with. Sometimes Dict inside dict inside dict ...... Initializing that nested dict is more complicated. I prefer to store the keys by a delimited char:

key = key1|key2|...|key3

When I need to access a specific "key" I just split the key and searching for the specific keys. What is better?

axcelenator
  • 1,497
  • 3
  • 18
  • 42

1 Answers1

1

Every time you are concatenating strings to use as a unified key, you are creating garbage for the garbage collector. This has a performance impact that is not trivial to measure, because you dοn't pay the price instantly. You are paying it when the garbage collection kicks in, and has more work to do than usual. Concatenating strings is also not a bullet proof approach, because it is based on the assumption that the delimiter (the pipe character in your example), is never contained in any of the subkeys.

My suggestion is to use value tuples as keys. For example in case each key is composed of 3 string parts, you could declare your dictionary like this:

Dictionary<(string, string, string), MyItem> dictionary = new();
//...
dictionary.Add(("key1", "key2", "key3"), new MyItem());
//...
if (dictionary.TryGetValue(("key1", "key2", "key3"), out var item)) //...

This will search for the keys with case sensitivity. In case you prefer your searches to be case insensitive, you could create a custom comparer that implements the IEqualityComparer<(string, string, string)> interface, implement accordingly the Equals and GetHashCode methods (look here for an example), and pass an instance to the constructor of the dictionary. You'll probably have to use the StringComparer.OrdinalIgnoreCase in the implementation.

Another option is to install the Nito.Comparers package, and create your comparer fluently like this:

var myComparer = Nito.Comparers.EqualityComparerBuilder
    .For<(string, string, string)>()
    .EquateBy(x => x.Item1, StringComparer.OrdinalIgnoreCase)
    .ThenEquateBy(x => x.Item2, StringComparer.OrdinalIgnoreCase)
    .ThenEquateBy(x => x.Item3, StringComparer.OrdinalIgnoreCase);
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104