I have two Dictionaries with around 65,000 KeyValuePairs each. I used foreach and if-else statements to compare them and get values, but it goes very slow. How could I optimize my code and gain more speed?
private void bgwCompare_DoWork(object sender, DoWorkEventArgs e)
{
var i = 0;
foreach (KeyValuePair<string, string> line1 in FirstDictionary)
{
foreach (KeyValuePair<string, string> line2 in SecondDictionary)
{
if (line1.Key == line2.Key)
{
ResultDictionary.TryAdd(line1.Value, line2.Value);
ListViewItem item = new ListViewItem(line1.Value);
item.SubItems.Add(line2.Value);
ResultList.Items.Add(item);
}
i++;
bgwCompare.ReportProgress(i * 100 / (FirstDictionary.Count() * SecondDictionary.Count()));
}
}
}
2 Answers 2
If I'm understanding it correctly, you're populating a ConcurrentDictionary from the values of two other ConcurrentDictionaries, where the keys are equal.
Try this, it's vastly faster than your loop in my tests.
var matches = FirstDictionary.Keys.Intersect(SecondDictionary.Keys);
foreach (var m in matches)
ResultDictionary.TryAdd(FirstDictionary[m], SecondDictionary[m]);
-
\$\begingroup\$ And now I need to go look up the
Intersect
implementation Im curious how MS optimized it. \$\endgroup\$RubberDuck– RubberDuck2016年05月01日 11:43:51 +00:00Commented May 1, 2016 at 11:43
Put simply you change an \$O(1)\$ operation to a \$O(n)\$ one.
Dictionary's have \$O(1)\$ key lookup and so if you change your inner loop to, SecondDictionary.TryGetValue
.
It'll achieve the same results without going through every item in SecondDictionary
.