并行化数组创建

时间:2012-11-21 02:12:20

标签: f# array-initialization

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

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

修改

我正在做的更多细节:

我有一个byte array array array的数字。我有另一个byte array array array,我正在比较其他人。我正在对可比较的%相似性进行排序并返回前500个。

在F#和C#中我都在做一个简单的嵌套for循环,它会增加一个计数器。完成循环遍历我的枚举中的特定项目时,我创建了一个元组(项目,计数器)。一旦完成创建我的新枚举(item,counter),我在计数器变量上进行排序,抓住前500,然后转换回只是一个可枚举的项目。

我在Parallel.For中放置的部分是IEnumerable<Tuple<item, int>>

的创建

2 个答案:

答案 0 :(得分:5)

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

官方文件:Parallel.init<'T> Function (F#)

答案 1 :(得分:3)

在这种情况下,您不应该使用数组解析。它比高阶函数慢一点,无法并行化。

虽然我更喜欢@ ildjarn的解决方案,但这是一个与C#one相同的解决方案:

// 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

它更加冗长,但让您可以更好地控制degree of parallelism