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# 会稍微快一些。使用Parallel.ForC# 只需一半的时间来执行。如何正确并行化 F# 以获得与 C# 相同的性能提升?

到目前为止我尝试过的方法是Array.Parallel.Iteri,所以我可以在 C# 中使用的数组技巧中使用相同的索引,但它减慢了速度而不是加快了速度。

编辑:

关于我在做什么的更多细节:

我有一个可枚举的byte array array array. 我有另一个byte array array array我正在比较其他人。我正在对可枚举的百分比相似性进行排序并返回前 500 个。

在 F# 和 C# 中,我都在做一个简单的嵌套 for 循环,它会增加一个计数器。当循环遍历我的可枚举中的特定项目时,我创建了一个 (item, counter) 的元组。完成创建新的 (item, counter) 可枚举项后,我对 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> Function (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 回答