使用'AsParallel()'/'Parallel.ForEach()'准则吗? [英] Using 'AsParallel()' / 'Parallel.ForEach()' guidelines?

查看:279
本文介绍了使用'AsParallel()'/'Parallel.ForEach()'准则吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就利用AsParallel()Parallel.ForEach()加快速度寻求一些建议.

Looking for a little advice on leveraging AsParallel() or Parallel.ForEach() to speed this up.

请参阅下面的方法(在本示例中为简化/标榜).

See the method I've got (simplified/bastardized for this example) below.

它包含一个列表,例如"US,FR,APAC",其中"APAC"是其他50个"US,FR,JP,IT,GB"等国家/地区的别名.该方法应采用"US,FR,APAC",并将其转换为"US","FR"以及"APAC"中所有国家/地区的列表.

It takes a list like "US, FR, APAC", where "APAC" is an alias for maybe 50 other "US, FR, JP, IT, GB" etc. countires. The method should take "US, FR, APAC", and convert it to a list of "US", "FR", plus all the countries that are in "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循环时应该使用什么经验法则?

Is making this parallelized as simple as changing it to what's below? Is there more nuance to using AsParallel() than this? Should I be using Parallel.ForEach() instead of foreach? What rules of thumb should I use when parallelizing 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查询的一部分.零件是空的,所以根本没有用.

writing just countriesAndAliases.AsParallel() is useless. AsParallel() makes part of Linq query that comes after it execute in parallel. Part is empty, so no use at all.

通常,您应将Parallel.ForEach()替换为foreach.但要注意不是线程安全的代码!你拥有了它.您不能将其包装到foreach中,因为List<T>.Add本身不是线程安全的.

generally you should repace foreach with Parallel.ForEach(). But beware of not thread safe code! You have it. You can't just wrap it into foreach because List<T>.Add is not thread safe itself.

所以您应该这样做(对不起,我没有测试,但是可以编译):

so you should do like this (sorry, i didn't test, but it compiles):

        return countriesAndAliases
            .AsParallel()
            .SelectMany(s => 
                IsCountryNotAlias(s)
                    ? Enumerable.Repeat(s,1)
                    : AliasCountryLists[s]
                ).Distinct();

修改:

您还必须确定另外两件事:

You must be sure about two more things:

  1. IsCountryNotAlias必须是线程安全的.最好是纯函数.
  2. 同时,没有人会修改AliasCountryLists,因为字典不是线程安全的.或使用 ConcurrentDictionary 来确定.
  1. IsCountryNotAlias must be thread safe. It would be even better if it is pure function.
  2. No one will modify AliasCountryLists in a meanwhile, because dictionaries are not thread safe. Or use ConcurrentDictionary to be sure.

有用的链接将为您提供帮助:

Useful links that will help you:

模式并行编程:使用.NET Framework 4理解和应用并行模式

中的并行编程. NET 4编码准则

我应该何时使用并行ForEach?什么时候应该使用PLINQ?

PS :如您所见,新的并行功能并不像外观(和感觉)那么明显.

PS: As you see new parallel features are not as obvious as they look (and feel).

这篇关于使用'AsParallel()'/'Parallel.ForEach()'准则吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆