如何并行编程?

How to program this in parallel?

我目前遇到以下代码的性能问题。

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>
    }
}

如何并行完成此操作。

您可以使用 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>
        }
    }
});

确保锁定您的字典或使用线程安全的字典类型。这是否有助于您的表现取决于内部采取的行动。如果它是基于 I/O 的,它可能没有那么大的好处,但你可以测试一下。

从技术上讲,它可以是这样的

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

但我怀疑性能问题是否真的出在这段代码中。 FilesIO 操作通常 )是 性能[=35= 最可能的来源] 问题。

P.S. 比较 浮点数 值与 == 操作 (Item2 == globalType2) 是可疑,因为 舍入错误 float globalType2 = 0.0342f; 很可能看起来是 0.03419999970.3420000002)。如果您必须使用 float 类型(而不是 intstring 等),请考虑与 tolerance 进行比较:更改 chunk.ift.Item2 == globalType2Math.Abs(chunk.ift.Item2 - globalType2) < 0.00001 或类似的。