首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化Parallel.For的性能

优化Parallel.For的性能
EN

Stack Overflow用户
提问于 2015-05-20 18:16:56
回答 3查看 456关注 0票数 3

我已经用Parallel.For替换了代码中的for循环。性能提升非常惊人(1/3的运行时间)。我尝试使用数组来收集结果代码来说明共享资源。然后,我在Parallel.For外部处理数组。这是最有效的方式吗?或者即使没有迭代可以共享相同的循环索引,阻塞仍然会发生吗?CompareExchange会有更好的表现吗?

代码语言:javascript
复制
int[] pageResults = new int[arrCounter];
Parallel.For(0, arrCounter, i =>
{
   AlertToQueueInput input = new AlertToQueueInput();
   input.Message = Messages[i];

   pageResults[i] = scCommunication.AlertToQueue(input).ReturnCode;
});

foreach (int r in pageResults)
{
    if (r != 0 && outputPC.ReturnCode == 0) outputPC.ReturnCode = r;
}
EN

回答 3

Stack Overflow用户

发布于 2015-05-20 19:08:54

这取决于你在主循环中是否有任何(有价值的)副作用。

outputPC.ReturnCode是唯一的结果时,你可以使用PLINQ:

代码语言:javascript
复制
outputPC.ReturnCode = Messages
    .AsParallel()
    .Select(msg =>    
    {
       AlertToQueueInput input = new AlertToQueueInput();
       input.Message = msg;        
       return scCommunication.AlertToQueue(input).ReturnCode;
    })
    .FirstOrDefault(r => r != 0);

这里假设scCommunication.AlertToQueue()是线程安全的,并且您不希望在出现第一个错误后为其余的项调用它。

请注意,PLinq中的FirstOrDefault()只是有效的in Framework 4.5 and later

票数 6
EN

Stack Overflow用户

发布于 2015-05-20 18:41:28

您可以替换:

代码语言:javascript
复制
foreach (int r in pageResults)
{
    if (r != 0 && outputPC.ReturnCode == 0) outputPC.ReturnCode = r;
}

通过以下方式:

代码语言:javascript
复制
foreach (int r in pageResults)
{
    if (r != 0)
    {
        outputPC.ReturnCode = r;
        break;
    }
}

这将在第一次失败时停止循环。

票数 3
EN

Stack Overflow用户

发布于 2015-05-20 18:51:41

我喜欢David Arno的解决方案,但正如我所见,您可以通过将检查放入并行循环中并直接从并行循环中中断来提高速度。无论如何,如果任何一次迭代失败,您都会让主代码失败,因此不需要进一步的迭代。

如下所示:

代码语言:javascript
复制
Parallel.For(0, arrCounter, (i, loopState) =>
{
   AlertToQueueInput input = new AlertToQueueInput();
   input.Message = Messages[i];
   var code = scCommunication.AlertToQueue(input).ReturnCode;
    if (code != 0)
    {
        outputPC.ReturnCode = code ;
         loopState.Break();
    }

});

更新1:

如果你需要保存所有迭代的结果,你可以这样做:

代码语言:javascript
复制
int[] pageResults = new int[arrCounter];
Parallel.For(0, arrCounter, (i, loopState) =>
    {
       AlertToQueueInput input = new AlertToQueueInput();
       input.Message = Messages[i];
       var code = scCommunication.AlertToQueue(input).ReturnCode;
       pageResults[i] = code ;
        if (code != 0 && outputPC.ReturnCode == 0)
            outputPC.ReturnCode = code ;    
    });

它将把你从foreach循环中解救出来,虽然这是一个很小的改进。

更新2:

刚刚发现了这个post,我认为自定义并行也是一个很好的解决方案。但这是你的决定,它是否适合你的任务。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30346774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档