标签: plinq

C#:AsParallel - 订单有关系吗?

我正在构建一个简单的LinQ-to-object查询,我想并行化,但是我想知道语句的顺序是否重要?

例如

IList<RepeaterItem> items;

var result = items
        .Select(item => item.FindControl("somecontrol"))
        .Where(ctrl => SomeCheck(ctrl))
        .AsParallel();
Run Code Online (Sandbox Code Playgroud)

var result = items
        .AsParallel()
        .Select(item => item.FindControl("somecontrol"))
        .Where(ctrl => SomeCheck(ctrl));
Run Code Online (Sandbox Code Playgroud)

会有什么不同吗?

plinq c#-4.0

15
推荐指数
1
解决办法
2863
查看次数

并行Linq查询优化

一段时间以来,我一直围绕没有副作用的方法构建我的代码,以便使用并行linq来加快速度.一路走来,我不止一次偶然发现懒惰的评估让事情变得更糟而不是更好,我想知道是否有任何工具可以帮助优化并行linq查询.

我问,因为我最近通过修改某些方法并AsParallel在某些关键位置加油来重构一些令人尴尬的并行代码.运行时间从2分钟下降到45秒,但从性能监视器可以清楚地看出,有些地方CPU上的所有内核都没有得到充分利用.在一些错误的启动后,我强制执行一些查询,ToArray并且运行时间进一步降低到16秒.减少代码的运行时间感觉很好,但它也有点令人不安,因为不清楚需要强制使用代码查询的位置ToArray.等到查询执行的最后一分钟不是最佳策略,但是根本不清楚代码中的哪些点需要强制某些子查询才能利用所有CPU内核.

因为它是我不知道如何正确胡椒ToArray或其他方法迫使linq计算执行,以获得最大的CPU利用率.那么优化并行linq查询是否有任何通用指南和工具?

这是一个伪代码示例:

var firstQuery = someDictionary.SelectMany(FirstTransformation);
var secondQuery = firstQuery.Select(SecondTransformation);
var thirdQuery = secondQuery.Select(ThirdTransformation).Where(SomeConditionCheck);
var finalQuery = thirdQuery.Select(FinalTransformation).Where(x => x != null);
Run Code Online (Sandbox Code Playgroud)

FirstTransformation,SecondTransformation,ThirdTransformation都是CPU绑定,并且在复杂性方面,他们有几个3x3矩阵乘法和一些if分支机构.SomeConditionCheck几乎是一张null支票.FinalTransformation是代码中CPU密集度最高的部分,因为它将执行一大堆线平面交叉,并检查这些交叉点的​​多边形包含,然后提取最接近线上某个点的交点.

我不知道为什么我放置的地方AsParallel减少了代码的运行时间.我现在已经达到了运行时间的局部最小值,但我不知道为什么.我偶然发现它只是运气不好.如果你想知道放置的地方AsParallel是第一行和最后一行.放在AsParallel其他地方只会增加运行时间,有时甚至会增加20秒.ToArray第一行还有隐藏的藏身之处.

c# linq parallel-processing plinq c#-4.0

15
推荐指数
2
解决办法
1万
查看次数

是否有PLINQ的异步版本?

我想在一定程度的并行处理并行处理项目的同时对数据流执行查询.通常情况下,我会使用PLINQ,但我的工作项不是CPU绑定的,而是IO绑定的.我想使用异步IO.PLINQ不支持异步工作.

运行PLINQ样式查询的最聪明方法是什么,但使用异步工作项?


以下是该问题的更详细说明:

我的目标是以下面的查询逻辑描述的方式处理可能无限的"项目"流:

var items = new int[10]; //simulate data

var results =
 from x in items.AsParallel().WithDegreeOfParallelism(100)
 where Predicate(x)
 select ComputeSomeValue(x);

foreach (var result in results)
 PerformSomeAction(result);
Run Code Online (Sandbox Code Playgroud)

此查询只是真实查询的草图.现在我希望每个占位符函数都是异步的(返回a Task和内部基于异步IO).

请注意,可能存在的内容远远多于可以存储在内存中的项目.我还必须控制并行度以最大化底层网络和磁盘硬件.

这个问题不是关于多核的.它完全适用于只有一个CPU内核的机器,因为IO仍然可以从并行性中受益.想想慢速的Web服务调用等.

.net asynchronous plinq task-parallel-library

14
推荐指数
2
解决办法
1027
查看次数

PLINQ执行比LINQ更糟糕

令人惊讶的是,使用PLINQ并没有为我创建的小测试案例带来好处; 事实上,它甚至比平时更糟糕的LINQ.

这是测试代码:

    int repeatedCount = 10000000;
    private void button1_Click(object sender, EventArgs e)
    {
        var currTime = DateTime.Now;
        var strList = Enumerable.Repeat(10, repeatedCount);
        var result = strList.AsParallel().Sum();

        var currTime2 = DateTime.Now;
        textBox1.Text = (currTime2.Ticks-currTime.Ticks).ToString();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        var currTime = DateTime.Now;
        var strList = Enumerable.Repeat(10, repeatedCount);
        var result = strList.Sum();

        var currTime2 = DateTime.Now;
        textBox2.Text = (currTime2.Ticks - currTime.Ticks).ToString();
    }
Run Code Online (Sandbox Code Playgroud)

结果?

textbox1: 3437500
textbox2: 781250
Run Code Online (Sandbox Code Playgroud)

因此,LINQ比PLINQ花费更少的时间来完成类似的操作!

我究竟做错了什么?还是有一种我不知道的扭曲?

编辑:我已经更新了我的代码以使用秒表,然而,相同的行为仍然存在.为了打折JIT的效果,我实际上尝试了几次点击两者button1并且button2没有特别的顺序.虽然我得到的时间可能不同,但定性行为仍然存在:在这种情况下PLINQ确实较慢.

c# plinq c#-4.0

13
推荐指数
3
解决办法
3428
查看次数

如何并行运行LINQ'let'语句?

我有这样的代码:

var list = new List<int> {1, 2, 3, 4, 5};

var result = from x in list.AsParallel()
             let a = LongRunningCalc1(x)
             let b = LongRunningCalc2(x)
             select new {a, b};
Run Code Online (Sandbox Code Playgroud)

让我们说LongRunningCalc每种方法需要1秒钟.上面的代码大约需要2秒才能运行,因为虽然5个元素的列表是并行操作的,但是从let语句中调用的两个方法是按顺序调用的.

但是,这些方法也可以安全地并行调用.他们显然需要合并回来,select但直到那时应该并行运行 - select应该等待它们.

有没有办法实现这个目标?

c# let plinq

13
推荐指数
1
解决办法
298
查看次数

List包含()PLinq?

假设我有一个大清单

List<long> longList = new List<long>(10000000)
Run Code Online (Sandbox Code Playgroud)

我想做以下查询:

bool found = longList.Contains(4345235234524245124L);
Run Code Online (Sandbox Code Playgroud)

有没有办法使用PLinq让每个线程只搜索列表的一小部分?

我知道在这种情况下使用Dictionary或HashMap会更好.这只是我想知道的关于PLinq的东西,这个例子非常方便.

.net c# .net-4.0 plinq

12
推荐指数
1
解决办法
642
查看次数

订购PLINQ ForAll

关于PLINQ中的订单保存的msdn文档说明了以下内容ForAll().

  • 订购源序列时的结果:并行执行非确定性
  • 源序列无序时的结果:并行执行非确定性

这是否意味着ForAll永远不能保证该方法的有序执行?

我以前没有使用PLINQ,但以下Code Review问题似乎是适合它的用法.在我的回答的底部,我写道:

Events.AsParallel().AsOrdered().ForAll( eventItem =>
{
    ...
} );    
Run Code Online (Sandbox Code Playgroud)

阅读文档后,我相信AsOrdered()不会改变任何东西?
我也怀疑以前的查询不能取代for顺序很重要的简单循环?
可能StringBuilder会发生与意志的并行调用,导致输出错误?

c# plinq

11
推荐指数
3
解决办法
6444
查看次数

使用TPL的Parallel.ForEach时跟踪进度

以下是跟踪进度的最佳方法

long total = Products.LongCount();
long current = 0;
double Progress = 0.0;

Parallel.ForEach(Products, product =>
{
    try
    {
        var price = GetPrice(SystemAccount, product);
        SavePrice(product,price);
    }
    finally
    {
        Interlocked.Decrement(ref this.current);
    }});
Run Code Online (Sandbox Code Playgroud)

我想将进度变量从0.0更新为1.0(当前/总)但我不想使用会对并行性产生负面影响的任何内容.

c# multithreading plinq task-parallel-library c#-4.0

11
推荐指数
2
解决办法
8967
查看次数

“使用静态”杀死 AsParallel

在以下代码中,如果取消注释“using static”行,查询将不会并行运行。为什么?

(Visual Studio 社区 2019,.Net Core 3.1 / .Net 4.8)

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace UsingStatic_Mystery
{
    //using static Enumerable;
    class Program
    {
        static void Main(string[] args)
        {
            var w = new Stopwatch();
            iter:
            w.Start();
            var xx = Enumerable.Range(0, 10)
                .AsParallel()
                .OrderByDescending(x => {
                    Thread.Sleep(new Random().Next(100));
                    Console.WriteLine(x);
                    return x;
                }).ToArray();
            w.Stop();
            Console.WriteLine();
            foreach (var x in xx) Console.WriteLine(x);
            Console.WriteLine(w.ElapsedMilliseconds);
            Console.ReadLine();
            w.Reset();
            goto iter;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出,未注释/注释:

“使用静态”未注释 “使用静态”评论

c# plinq

11
推荐指数
1
解决办法
330
查看次数

PLINQ有什么实际好处?

最近我对Linq和Plinq采取了一些措施.我无法看出Plinq在哪种情况下具有真正的显着优势.

我发现了许多例子,例如:

Enumerable.Range(0, 10000).AsParallel().ForAll(_ => Thread.Sleep(50000));
Run Code Online (Sandbox Code Playgroud)

这是完全没用的例子,因为它可以平均10000度,然后会更快10000倍,但在业务应用程序中很少循环10000次并制作"IO作业".

如果有人可以提一个例子,请发布.

Plinq仅适用于Linq to Objects和Linq to XML.不建议在webserver上运行的应用程序中使用它(它有自己的线程管理).因此,我们的机会减少到具有多个核心的桌面应用程序.

通常我会编写linq查询,这些查询在几分之一秒内按顺序运行.如果我平行化并且它真的会并行运行那么会更快,但是谁在乎呢?我认为它仍然足够快.最终用户不会看到任何差异.

我可以想象一个例子,当有人从数据库获取所有数据并在内存中运行查询时.也许这很有用,但这是一个错误的设计.

TPL是异步程序编程的好东西,但我仍然不确定Plinq是一个有用的工具.

有没有人有这方面的积极经验?

c# plinq

9
推荐指数
1
解决办法
837
查看次数