优化F#中的nbody算法

时间:2011-11-01 08:50:53

标签: algorithm optimization f#

如何进一步优化此代码:

let rec nCollect func = function
        | [] -> []
        | x::xs -> let firstAndNext body (firstBody, ys) = 
                        let newFirst, z = func firstBody body
                        newFirst, z::ys
                   let y, ys = List.foldBack firstAndNext xs (x, [])
                   y::(nCollect func ys)

此代码是nbody模拟程序的一部分。它正在获取每个正文并在它和下一个之间应用函数函数。结果用于下一次迭代。我用列表略微优化了它。问题是输入体的计数低于10,但nCollect被称为数百万次。例如,如果我在nCollect中使用尾递归,结果会更糟。

3 个答案:

答案 0 :(得分:5)

我认为每种语言中90%的微优化问题的答案总是相同的:使用数组,循环和变异。

所以,我会使用数组,循环和变异,而不是List.foldBack

答案 1 :(得分:1)

一些快速评论

List.Fold应该击败List.FoldBack。查看此处的代码 - https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/list.fs,您可以看到FoldBack将分配一个临时数组,这可能很慢,而折叠可以快速遍历列表。

您还可以尝试内联firstAndNext

手动展开循环也有帮助

答案 2 :(得分:1)

  1. 使用更好的算法,如Ewald求和或快速多极法(FMM)。

  2. 使用数组和for循环替换列表和递归函数。

  3. 对于小问题,请使用自定义代码生成替换循环。