我有一个返回从0开始按照跳n、选n的模式排列的数字列表的F#函数,直到达到限制。例如,输入2的这个函数将返回
最初我实现了一个非尾递归函数,如下所示:
然而,当我在Mono下以参数1、1和20,000运行它时(即应该返回
为什么尾递归版本更慢呢?是因为列表连接吗?还是编译器优化?我是否实际上已经实现了尾递归?
我也觉得我应该使用高阶函数来完成这个任务,但我不确定如何去做。
[2, 3, 6, 7, 10, 11...]
。最初我实现了一个非尾递归函数,如下所示:
let rec indicesForStep start blockSize maxSize =
match start with
| i when i > maxSize -> []
| _ -> [for j in start .. ((min (start + blockSize) maxSize) - 1) -> j] @ indicesForStep (start + 2 * blockSize) blockSize maxSize
认为尾递归是可取的,我使用累加器列表重新实现了它,如下所示:
let indicesForStepTail start blockSize maxSize =
let rec indicesForStepInternal istart accumList =
match istart with
| i when i > maxSize -> accumList
| _ -> indicesForStepInternal (istart + 2 * blockSize) (accumList @ [for j in istart .. ((min (istart + blockSize) maxSize) - 1) -> j])
indicesForStepInternal start []
然而,当我在Mono下以参数1、1和20,000运行它时(即应该返回
[1, 3, 5, 7...]
,直到20,000),尾递归版本比第一版本慢得多(需要12秒,而不是亚秒级)。为什么尾递归版本更慢呢?是因为列表连接吗?还是编译器优化?我是否实际上已经实现了尾递归?
我也觉得我应该使用高阶函数来完成这个任务,但我不确定如何去做。