是否可以将PLINQ查询的线程“索引”传递给其中一个运算符,如Select?
背景是我有一个PLINQ查询进行一些反序列化,反序列化方法使用一个结构(可能是一个数组)将数据传递给另一个方法:
ParallelEnumerable.Range(0, nrObjects)
.WithDegreeOfParallelism(8)
.Select(i => this.Deserialize(serializer, i, arrays[threadIndex]))
.ToList();
(threadIndex是我想要的新变量)
如果我知道线程索引,我可以预先创建8个这些数组(即使所有数组都可能没有使用)并重用它们。反序列化方法可能会被调用数百万次,因此每个小优化都会计算在内。
答案 0 :(得分:1)
重新线程索引;请注意,并行度是(IIRC)仅使用最大线程数;它不 使用该号码。以您描述的方式依赖threadIndex
似乎意味着您实际只能访问arrays[0]
。所以简而言之,不:我不这么认为。
可以获取项索引;所以,如果这就是你的意思,那就简单地说:
.Select((value, itemIndex) => this.Deserialize(
serializer, i, arrays[itemIndex])).ToList();
听起来像(评论),意图是获得工作缓冲区;在这种情况下,我会(实际上,做)在容器中保留一些方便的缓冲区(具有同步访问等),即
这通常非常快(比每次迭代的缓冲区分配快得多)
答案 1 :(得分:0)
您可以创建ConcurrentBag
个整数,然后在将deserealization用作索引之前取出它,然后返回。每个线程一次占用一个数组元素。
考虑使用Parallel class。在阵列方面更合适。如果您使用Select
,则ParallelEnumerable
的索引版本存在限制(不是在您的情况下,但要谨慎)
答案 2 :(得分:0)
我建议使用Parallel.ForEach which offers an overload that allows you to allocate (and cleanup) locals,它将一次传递到循环的一个并行实例中。我已经使用这种方法处理大量图像数据,其中我需要缓冲区来处理该过程的各个步骤。