Algorithm F中nbody算法的优化#
如何进一步优化此代码:Algorithm F中nbody算法的优化#,algorithm,optimization,f#,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 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仿真程序的一部分。它获取每个主体,并在主体和下一个主体之间应用func函数。结果将用于下一次迭代。我用列表稍微优化了一下。问题是,输入主体的计数不到10,但nCollect被称为数百万次。例如,如果我在nCollect中使用尾部递归,结果会更糟。我认为每种语言中90%的微观优化问题的答案都是相同的:使用数组、循环和变异
因此,我会使用数组、循环和变异,而不是
列表。折叠我认为每种语言中90%的微观优化问题的答案都是一样的:使用数组、循环和变异
因此,我会使用数组、循环和变异,而不是List.foldBack
一些快速注释
List.Fold
应该优于List.FoldBack
。看看这里的代码,您可以看到FoldBack将分配一个临时数组,这可能会很慢,而fold可以快速遍历列表
您也可以尝试内联firstAndNext
手动展开循环也会有帮助一些快速评论
List.Fold
应该优于List.FoldBack
。看看这里的代码,您可以看到FoldBack将分配一个临时数组,这可能会很慢,而fold可以快速遍历列表
您也可以尝试内联firstAndNext
手动展开循环也会有所帮助
使用更好的算法,如Ewald求和或快速多极方法(FMM)
将列表和递归函数替换为数组和for
循环
对于小问题,使用自定义代码生成替换循环
使用更好的算法,如Ewald求和或快速多极方法(FMM)
将列表和递归函数替换为数组和for
循环
对于小问题,使用自定义代码生成替换循环
除了尾部递归,你还尝试了什么?您是否有一个测试显示了问题?除了尾部递归,您还尝试了什么?是否有测试显示了问题?List.foldBack本质上是一个循环,但问题在于从循环体(firstBody)创建的中间数据。如果它足够聪明,可以将内存位置重新用于中间存储,那么就可以了。但是编译器会产生这样的魔力吗?@幽灵:如果很容易判断一个方法是否是纯的,那么这是可能的,但是在F中这是非常困难的。容易访问mutability.List.foldBack的问题之一是循环的本质,但问题在于从循环体(firstBody)创建的中间数据。如果它足够聪明,可以将内存位置重新用于中间存储,那么就可以了。但是编译器会产生这样的魔力吗?@幽灵:如果很容易判断一个方法是否是纯的,那么这是可能的,但是在F中这是非常困难的。易访问易变性的问题之一是内联没有帮助。奇怪的是,在我的情况下,折回运行得更快。内联没有帮助。奇怪的是,在我的情况下,折叠运行得更快。