使用“AsParallel()”/“Parallel.ForEach()”指南?

2024-03-31

寻求一些关于利用杠杆的建议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:

您还必须确定两件事:

  1. IsCountryNotAlias必须是线程安全的。如果是的话那就更好了纯函数 http://en.wikipedia.org/wiki/Pure_function.
  2. 没有人会修改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(使用前将#替换为@)

使用“AsParallel()”/“Parallel.ForEach()”指南? 的相关文章

随机推荐