【问题标题】:Can I perform Linq OrderBy with asynchronous calls in parallel?我可以通过异步调用并行执行 Linq OrderBy 吗?
【发布时间】:2012-05-22 03:15:23
【问题描述】:

我有一个 linq 查询的订单,像这样:

var sortedList = unsortedList
                    .OrderBy(foo => foo.GetCurrentValue())

但是,GetCurrentValue 方法响应缓慢(因为它涉及网络通信并且具有相当大的延迟)。据我观察,上面的代码顺序调用方法(调用必须在下一个调用之前完成,所以如果列表很长,排序会很慢。

有没有办法告诉 linq 并行执行?即异步计算表达式,然后在每个人完成后比较结果?

如果没有,知道如何干净、轻松地制作我们自己的实现吗?

【问题讨论】:

  • 在 PLINQ (AsParallel) 查询上调用 OrderBy 将自动将查询视为 AsOrdered - msdn.microsoft.com/en-us/library/dd460677.aspx 我不确定这会对性能产生什么影响,MSDN文章对此并不清楚。
  • @Snixtor 这是一个非常有用的链接,它可能会解决我的问题(现在测试)!为什么不将其发布为答案?

标签: c# .net linq sorting asynchronous


【解决方案1】:

MSDN 在 PLINQ 中有一篇专门关于“订单保留”的文章 - http://msdn.microsoft.com/en-us/library/dd460677.aspx(根据我之前的评论)。链接给出的示例:

var cityQuery = (from city in cities.AsParallel()
                 where city.Population > 10000
                 select city);

只是把它作为一个可能的实现扔出去,像这样?其中slowList 是您的“慢”对象的可枚举集合。 Parallel.ForEach 可以替换为任何其他异步“暂存”操作以收集慢速值。

    var stage1List = new List<dynamic>();
    var parOpt = new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = 30 };

    System.Threading.Tasks.Parallel.ForEach(slowList, parOpt, slowObj =>
    {
        stage1List.Add(new { Obj = slowObj, Value = slowObj.GetSlowValue() });
    });

    var stage2List = stage1List.OrderBy(p => p.Value).Select(p => p.Obj);

【讨论】:

  • unsortedList.AsParallel().OrderBy(foo =&gt; foo.GetSlowValue()) 似乎有效时,为什么还需要这样的实现?
  • 我认为没有办法在AsParallel 上指定并行度?这就是说,Parallel.ForEach,尽管允许 MaxDegreeOfParallelism 的规范并不一定将其并行化到最大程度。我的思路是 GetSlowValue() 调用可能会因为本地处理能力限制以外的原因而变慢,因此一次对 30 个项目执行该方法可能会产生更好的性能?本质上,这是并行性的常见问题 - 多少?
  • 缓慢是由于网络延迟,而不是处理能力,所以如果我并行化它们确实会变得更快。理论上,我认为更多的并行性总是意味着更好的性能。如果我只指定 AsParallel,知道它们使用什么级别的并行度吗?
猜你喜欢
  • 2019-04-21
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多