我目前遇到以下代码的性能问题。
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>
}
}
我如何能够并行完成此任务。
答案 0 :(得分:1)
从技术上讲,它可能是这样的
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
但我怀疑性能问题是否真的存在于此代码片段中。 Files
( IO 操作通常慢操作)是性能问题的最可能来源。
PS 将浮点值与==
操作(Item2 == globalType2
)进行比较是不确定的,因为舍入错误 (float globalType2 = 0.0342f;
似乎可能是0.0341999997
或0.3420000002
)。如果您必须使用float
类型(不是int
,string
等),请考虑与容差进行比较:将chunk.ift.Item2 == globalType2
更改为Math.Abs(chunk.ift.Item2 - globalType2) < 0.00001
或类似的。
答案 1 :(得分:0)
您可以使用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的,它可能不会那么受益,但你可以测试它。