如何进一步优化此代码:
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中使用尾递归,结果会更糟。
答案 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)
使用更好的算法,如Ewald求和或快速多极法(FMM)。
使用数组和for
循环替换列表和递归函数。
对于小问题,请使用自定义代码生成替换循环。