There is a task. The array contains arbitrary strings. We need to count how many times each of the strings occurs in the array. Solve the task in one thread and multithreaded, compare the execution time.
For some reason, the single-threaded version runs faster than the multi-threaded one: 90 ms versus 300 ms. How to fix the multi-threaded version so that it runs faster than the single-threaded one?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
namespace ParallelDictionary
{
class Program
{
static void Main(string[] args)
{
List<string> strs = new List<string>();
for (int i=0; i<1000000; i++)
{
strs.Add("qqq");
}
for (int i=0;i< 5000; i++)
{
strs.Add("aaa");
}
F(strs);
ParallelF(strs);
}
private static void F(List<string> strs)
{
Dictionary<string, int> freqs = new Dictionary<string, int>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i=0; i<strs.Count; i++)
{
if (!freqs.ContainsKey(strs[i]))
freqs[strs[i]] = 1;
else
freqs[strs[i]]++;
}
stopwatch.Stop();
Console.WriteLine("single-threaded {0} ms", stopwatch.ElapsedMilliseconds);
foreach (var kvp in freqs)
{
Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);
}
}
private static void ParallelF(List<string> strs)
{
ConcurrentDictionary<string, int> freqs = new ConcurrentDictionary<string, int>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Parallel.ForEach(strs, str =>
{
freqs.AddOrUpdate(str, 1, (key, value) => value + 1);
});
stopwatch.Stop();
Console.WriteLine("multi-threaded {0} ms", stopwatch.ElapsedMilliseconds);
foreach (var kvp in freqs)
{
Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);
}
}
}
}