首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么从左到右的函数组合比从右到左的速度快11倍到19倍?

为什么从左到右的函数组合比从右到左的速度快11倍到19倍?
EN

Stack Overflow用户
提问于 2014-05-26 18:04:16
回答 1查看 198关注 0票数 7

在写我可怜人的FParsec版本时,我遇到了这种现象。考虑:

代码语言:javascript
复制
let add x = x+1
let fromLeft  = add>>add>>add>>add>>add>>add>>add>>add>>add>>add
let fromRight = add<<add<<add<<add<<add<<add<<add<<add<<add<<add
let imperative x =
    let mutable result = x
    for i = 0 to 9 do
        result <- add result
    result

并测试所有三个功能的性能:

代码语言:javascript
复制
let runs = 10000000
printf "From left\n"
time(fun()->fromLeft 0) runs
printf "\nFrom right\n"
time(fun()->fromRight 0) runs
printf "\nImperative\n"
time(fun()->imperative 0) runs

结果表明:fromLeft为59 ms,fromRight为65 8ms,Imperative为26 ms。

该测试是在版本模式和VS之外进行的。结果是稳定的,不取决于我测试函数的顺序。如果将Imperative运行时视为add函数本身的开销,并从这两个结果中减去,则两个组合性能不同的因素是11倍或19倍。

有谁知道出现这种差异的原因吗?

我的time组合器是

代码语言:javascript
复制
let inline time func n =
    GC.Collect()
    GC.WaitForPendingFinalizers()
    printfn "Starting"
    let stopwatch = Stopwatch.StartNew()
    for i = 0 to n-1 do func() |> ignore
    stopwatch.Stop()
    printfn "Took %A ms" stopwatch.Elapsed.TotalMilliseconds
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-26 20:45:25

一个非常粗略的答案是,编译器在fromLeft中嵌入了函数,但出于某种原因,它没有对fromRight进行相同的优化。完全用圆括号表示这样的构图是可以强制结合的:

代码语言:javascript
复制
let fromLeft  = add>>(add>>(add>>(add>>(add>>(add>>(add>>(add>>(add>>add))))))))
let fromRight = ((((((((add<<add)<<add)<<add)<<add)<<add)<<add)<<add)<<add)<<add

其结果是:

代码语言:javascript
复制
From left
Starting
Took 645.648 ms

From right
Starting
Took 625.058 ms

Imperative
Starting
Took 23.0332 ms

将圆括号颠倒如下:

代码语言:javascript
复制
let fromLeft = ((((((((add>>add)>>add)>>add)>>add)>>add)>>add)>>add)>>add)>>add
let fromRight  = add<<(add<<(add<<(add<<(add<<(add<<(add<<(add<<(add<<add))))))))

在以下方面的成果:

代码语言:javascript
复制
From left
Starting
Took 86.3503 ms

From right
Starting
Took 75.6358 ms

Imperative
Starting
Took 33.7193 ms

这看起来就像是编译器中缺少的一个优化。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23875598

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档