How to program this in parallel?

98 views Asked by At

I am currently facing a performance problem with the following code.

private int globalType1 = 1;
private float globalType2 = 0.0342f;
private Dictionary<string, Tuple<int, float>> dt = new Dictionary<string, Tuple<int, float>>();

foreach (string file in Files) //assume 100 distinct files
{
    //GetType1AndType2 is thread safe
    Tuple<int, float> ift = GetType1AndType2(file, 0); //here 0 is the version of the file.

    if (ift.Item1 == globalType1 && ift.Item2 == globalType2)
    {
        dt.Add(file + "_0", fftandFreq); //Key = <FileName_Version> ; Value = Tuple<Type1, Type2>
    }
}

How can I accomplish this in parallel.

2

There are 2 answers

2
Patrick Hofman On BEST ANSWER

You can use Parallel.Foreach:

Parallel.Foreach(Files, file => 
{
    //GetType1AndType2 is thread safe
    Tuple<int, float> ift = GetType1AndType2(file, 0); //here 0 is the version of the file.

    if (ift.Item1 == globalType1 && ift.Item2 == globalType2)
    {
        lock (dt)
        {
            dt.Add(file + "_0", fftandFreq); //Key = <FileName_Version> ; Value = Tuple<Type1, Type2>
        }
    }
});

Make sure to lock your dictionary or use a thread-safe dictionary type. Whether this helps your performance or not depends on the actions take inside. If it is I/O based it might not benefit that much, but you can test that.

0
Dmitry Bychenko On

Technically it can be something like this

private Dictionary<string, Tuple<int, float>> dt = Files
  .AsParallel() // PLinq - parallel Linq
  .Select(file => new {
     ift = GetType1AndType2(file, 0),
     file = file})
  .Where(chunk => chunk.ift.Item1 == globalType1 && 
                  // Math.Abs(chunk.ift.Item2 - globalType2) < 0.00001
                  chunk.ift.Item2 == globalType2) 
  .ToDictionary(chunk => chunk.file + "_0",
                chunk => chunk.ift); //TODO: check the value, please

But I doubt if the perfomance problem is actually in this code fragment. Files (IO operations are often slow ones) is the most probable source of the perfomance issue.

P.S. Comparing floating point values with == operation (Item2 == globalType2) is dubious because of round up errors (float globalType2 = 0.0342f; can well appear to be 0.0341999997 or 0.3420000002). If you have to use float type (not int, string etc.), please, think on comparing with tolerance: change chunk.ift.Item2 == globalType2 to Math.Abs(chunk.ift.Item2 - globalType2) < 0.00001 or alike.