2017-01-12 25 views
1

Iコードを以下た:遅延評価

static IEnumerable<int> foo() 
{ 
    int den = 0; 
    yield return 10; 
    yield return 10; 
    yield return 10; 
    yield return 10/den; 
    yield return 10/den; 
} 
static public void Main() 
{ 
    foreach (var item in foo().AsParallel().Take(3)) 
    { 
     Console.WriteLine(item); 
    } 
    Console.ReadLine(); 
} 

このコードは失敗した(収集の実際に使用されていない要素が計算されるため、 - PLINQは、データのチャンクを計算します)。 .Netは本当の "遅延"並列化をサポートしていますか?(未使用要素のチャンクの事前計算なし)

注:これは単なる例に過ぎません。オーバーヘッドを避けるために大きなデータにはAsParallelを使用する必要があります。

+3

私に何かが不足していますか?あなたは順序を変更する必要がありますよね? 'foo()。Take(3).AsParallel()' – wdosanjos

+0

違いは何ですか? – LmTinyToon

+3

'AsParallel()'は後ろに何が来るのか分からないので、コレクション内のすべての項目を並列化するため、エラーが発生します。 'Take(3).AsParallel()'は最初の3つの要素をとり、それらを並列化します。したがって、エラーはありません。 – wdosanjos

答えて

1

チャンクの事前計算を禁止すると、並行して作業を行うことはできません。 ストリーミング演算子のいずれかを並列化する方法は、データソースの項目をより多くクエリすることができ、必要な値を事前に計算しておくことができます。データの事前計算を許可できない場合、定義上、これらの演算子の処理を並行して実行することはできず、単にPLINQではなく通常のLINQ演算を使用するだけです。

+0

なぜplinqが未使用の余分な要素を処理するのですか?余分な要素を事前計算するのはなぜですか?私はこの考えを理解できません。私はなぜ計算されたチャンクを格納する方が並列的に優れたパフォーマンスをもたらすのか理解できません。 – LmTinyToon

+0

@LmTinyToon要求されたアイテムのみを処理する場合は、*定義で*一度に1つのアイテムを処理しています。あなたが処理する複数のアイテムを持つことができる唯一の可能な方法は、あなたにまだ尋ねられていないアイテムより多くのアイテムを求めることです。 – Servy

関連する問題