并行化阵列创建



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 循环,该循环会增加计数器。 遍历枚举中的特定项后,我创建一个元组(项、计数器)。 完成创建新的可枚举项(项目,计数器)后,我在计数器变量上对其进行排序,获取前 500 个,然后转换回可枚举的项目。

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

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

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

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

虽然我更喜欢@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

它更详细,但可以更好地控制并行度。

相关内容

  • 没有找到相关文章

最新更新