0

I have two sorted dictionaries. The first one is just filled with NANs, the second one has some values.

I want to change NANs of the first one to values of the second one.

SortedDictionary<double, float> newlogdict = newlog.Samples;
SortedDictionary<double, float> oldlogdict = oldlog.Samples;

foreach (KeyValuePair<double, float> kvp in newlogdict)
{
    oldlogdict[kvp.Key] = kvp.Value;
}

It works, but it is too slow, is there any faster way?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
  • 3
    How fast do you want this? You're going to have to touch every element in the dictionary anyway, so there's not much fat that can be removed here, if at all. – Robert Harvey Jan 02 '19 at 16:36
  • As fast as it can :) –  Jan 02 '19 at 16:41
  • 2
    Double seems like a weird key type for a Dictionary, what with rounding and all. It strikes me odd that a type that should never really be checked for equality should be the key. Now, you aren't checking the value, you are checking the hash, but it still isn't something I'd do. – Flydog57 Jan 02 '19 at 16:45
  • 1
    Why don't you just pass `newlogdict` to the constructor of `oldlogdict` and see if it makes a difference. If it doesn't and it is still slow, then you need to change your design somehow so the slowness doesn't hinder the system. – CodingYoshi Jan 02 '19 at 16:56
  • Why do you need `SortedDictionary`? You could actually increase your performance by using `Dictionary` instead. Check this link out: https://www.dotnetperls.com/sorteddictionary – Szab Jan 02 '19 at 16:58
  • SortedDictionary is implemented as a tree. I would simply put the things into a Dictionary. That should be significantly faster when it comes to merging. Do you need this sorted at all times? – Alois Kraus Jan 02 '19 at 17:37
  • 1
    Not a good idea to use floating points as a key because of imprecision as soon as you do some computation (i.e. (1.0 / 3.0) * 3.00 might give 0.999.. instead of 1) – Phil1970 Jan 02 '19 at 17:38
  • What is the size of old and new dictionary before merge? Do you insert new keys after initial fill? Is NAN used for values, for keys or both (not clear in the question)? Do you really need 2 dictionaries and not one with both old and new value or directly update the single dictionary? – Phil1970 Jan 02 '19 at 17:42

2 Answers2

1

It is slow because your code increases the size oldlogdict (maybe it is doubling it). If the

oldlogdict[kvp.Key]

in not found, then you are adding a new element with the following line

oldlogdict[kvp.Key] = kvp.Value;

I tested your code with this sample data:

SortedDictionary<double, float> newlogdict = new SortedDictionary<double, float>();
SortedDictionary<double, float> oldlogdict = new SortedDictionary<double, float>();

float x1 = 3.5F;
double a = 3.3;

newlogdict.Add(double.NaN, x1);
oldlogdict.Add(a, x1);

foreach (KeyValuePair<double, float> kvp in newlogdict)
{
    oldlogdict[kvp.Key] = kvp.Value;      //if key is not found it will be added
}

Console.WriteLine(newlogdict.Count);
Console.WriteLine(oldlogdict.Count);

Please also note that in a SortedDictionary a KeyNotFoundException will only be thrown during a Get and not Set as documented on MSDN.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
ES2018
  • 438
  • 3
  • 15
-1

This is concating or merging, mentioned here

seems there is no faster way, but there is shorter code

Serg Shevchenko
  • 662
  • 1
  • 5
  • 21