Clojure 1.5 のライブラリに触発されてreducers
、私は PLINQ のParallelEnumerable.Aggregate()
メソッドを同じように動作させることを試みてきました。ほとんどの場合、それは非常に簡単です。
ただし、存在する可能性があると思われる動作の違いが 1 つあります。2007 CTP に関する Igor Ostrovsky のブログ投稿combineAccumulatorsFunc
で、彼はそれが交換可能でなければならないと主張しています。現代のドキュメンテーションは、それが交換可能でなければならないことについて何も言っていないようで、交換可能性に依存することを強制することはできませんでしたが、それを強制することもできませんでした結合性に依存します。
主な質問:のセマンティクスはcombineAccumulatorsFunc
どこでも定義されていますか? そうでない場合でも、連想的に呼び出される可能性があるが交換可能に呼び出される可能性があると仮定しても大丈夫でしょうか?
次の LINQPad スニペットを使用して、順不同のcombineAccumulatorsFunc
呼び出しを発生させようとしています。
ParallelEnumerable.Range(0,1000000).AsUnordered().WithDegreeOfParallelism(10).
WithExecutionMode(ParallelExecutionMode.ForceParallelism).
Aggregate<int,IImmutableList<int>,IEnumerable<int>>(
() => { Thread.Sleep(new Random().Next(5000)); return ImmutableList<int>.Empty; },
(L,n) => n % 2 == 0 ? L.Add(n) : L,
(L1,L2) => {new {L1 = L1.First(),L2 = L2.First()}.Dump("partition"); return L1.Concat(L2).ToImmutableList();},
x => x.AsEnumerable()
).Dump();