寻求一些关于利用杠杆的建议AsParallel()
or Parallel.ForEach()
以加快速度。
请参阅下面我得到的方法(此示例的简化/粗制化)。
它需要一个类似“美国、法国、亚太地区”的列表,其中“亚太地区”可能是其他 50 个“美国、法国、日本、意大利、英国”等国家的别名。该方法应采用“US、FR、APAC”,并将其转换为“US”、“FR”以及“APAC”中的所有国家/地区的列表。
private IEnumerable<string> Countries (string[] countriesAndAliases)
{
var countries = new List<string>();
foreach (var countryOrAlias in countriesAndAliases)
{
if (IsCountryNotAlias(countryOrAlias))
{
countries.Add(countryOrAlias);
}
else
{
foreach (var aliasCountry in AliasCountryLists[countryOrAlias])
{
countries.Add(aliasCountry);
}
}
}
return countries.Distinct();
}
使其并行化就像将其更改为下面的内容一样简单吗?使用上还有更多细微差别吗AsParallel()
比这个?我应该使用Parallel.ForEach()
代替foreach
?并行化时应该使用哪些经验法则foreach
loops?
private IEnumerable<string> Countries (string[] countriesAndAliases)
{
var countries = new List<string>();
foreach (var countryOrAlias in countriesAndAliases.AsParallel())
{
if (IsCountryNotAlias(countryOrAlias))
{
countries.Add(countryOrAlias);
}
else
{
foreach (var aliasCountry in AliasCountryLists[countryOrAlias].AsParallel())
{
countries.Add(aliasCountry);
}
}
}
return countries.Distinct();
}
几点。
只写countriesAndAliases.AsParallel()
是没用的。AsParallel()
使 Linq 查询的一部分并行执行。部分是空的,所以根本没有用。
一般来说你应该重新更换foreach
with Parallel.ForEach()
。但要注意非线程安全的代码!你拥有了它。你不能只是把它包装成foreach
因为List<T>.Add
本身不是线程安全的。
所以你应该这样做(抱歉,我没有测试,但它可以编译):
return countriesAndAliases
.AsParallel()
.SelectMany(s =>
IsCountryNotAlias(s)
? Enumerable.Repeat(s,1)
: AliasCountryLists[s]
).Distinct();
Edit:
您还必须确定两件事:
-
IsCountryNotAlias
必须是线程安全的。如果是的话那就更好了纯函数 http://en.wikipedia.org/wiki/Pure_function.
- 没有人会修改
AliasCountryLists
同时,因为字典不是线程安全的。或者使用并发词典 http://msdn.microsoft.com/en-us/library/dd287191.aspx为了确定。
对您有帮助的有用链接:
.NET 4 中的并行编程编码指南 http://download.microsoft.com/download/B/C/F/BCFD4868-1354-45E3-B71B-B851CD78733D/ParallelProgramsinNET4_CodingGuidelines.pdf
我什么时候应该使用Parallel.ForEach?我什么时候应该使用 PLINQ? http://download.microsoft.com/download/B/C/F/BCFD4868-1354-45E3-B71B-B851CD78733D/WhenToUseParallelForEachOrPLINQ.pdf
PS:正如您所见,新的并行功能并不像它们看起来(和感觉)那么明显。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)