3

F#

[|for index in 1 .. items.Count()-1 -> (* create object here - complex operations *)|]

C#

Object[] newItemArray= new Object[items.Count];

Parallel.For(0, items.Count, index=>
{
    /*complex stuff here*/
    newItemArray[index] = new Object();
});

上記の C# と F# で同じことをしています。Parallel.ForF# を使用しない場合は、わずかに高速です。C# を使用するParallel.Forと、実行にかかる時間が半分になります。F# を適切に並列化して、C# と同じパフォーマンスを向上させるにはどうすればよいですか?

私がこれまでに試した方法は だったArray.Parallel.Iteriので、C# で使用した配列トリックに同じインデックスを使用できましたが、高速化する代わりに低速化しました。

編集:

私がやっていることの詳細:

列挙可能な がありbyte array array arrayます。私は他のbyte array array arrayものと比較している別のものを持っています。列挙可能なものを類似度 % でソートし、最初の 500 を返します。

F# と C# の両方で、カウンターをインクリメントする単純なネストされた for ループを実行しています。Enumerable 内の特定のアイテムをループ処理したら、(item, counter) のタプルを作成します。(アイテム、カウンター) の新しい列挙型の作成が完了したら、それをカウンター変数で並べ替え、最初の 500 を取得してから、アイテムの列挙型に戻します。

Parallel.For の中に入れている部分は、IEnumerable<Tuple<item, int>>

4

2 に答える 2

5
Array.Parallel.init items.Count (fun index ->
    (* create object here - complex operations *))

公式ドキュメント:Parallel.init <'T>関数(F#)

于 2012-11-21T02:19:27.930 に答える
3

この場合、配列内包表記を使用しないでください。高階関数よりも少し遅く、並列化できません。

私は @ildjarn のソリューションを好みますが、C# のソリューションと同等のソリューションを次に示します。

// You need an uninitialized array to fill in later
let newItemArray = Array.zeroCreate items.Count

// Fill in the array in a parallel manner
Array.Parallel.iteri (fun i v ->
    (* create object here - complex operations *)) newItemArray

直接使用することもできParallel.Forます:

let newItemArray = Array.zeroCreate items.Count 

Parallel.For(0, items.Count, 
             (fun index ->
                 (* complex stuff here *)
                 newItemArray.[index] <- Object())
) |> ignore

より冗長ですが、並列処理の度合いをより細かく制御できます。

于 2012-11-21T02:25:24.630 に答える