查看今天我的代码中的函数,我想知道是否可以组合部分组合和优化:
let foo (X:float) y1 y2 dx =
y1 + (y2 - y1) * dx / X
Run Code Online (Sandbox Code Playgroud)
基本上,只需应用一个比率 - 所以前三个参数在给定的循环中通常是相同的.
我想也许如果我这样做:
let foo2 (X:float) y1 y2 dx =
let dy = (y2 - y1) / X
y1 + dy * dx
Run Code Online (Sandbox Code Playgroud)
当我部分应用前三个参数时,F#会变得聪明并为我优化,但是调试模式似乎并非如此(尽管我不确定我是否以正确的方式测试它).
问题是,这应该有效吗?如果不是有更好的方法(除了用两个参数编写另一个函数)?
我认为大多数此类“神奇优化”都需要“效果分析”,而这只能由神话般的“足够智能的编译器”来完成。
思考一下:
let Expensive x y =
printfn "I am a side-effect of Expensive"
x + y // imagine something expensive
let F x y z =
let tmp = Expensive x y
z + tmp
printfn "Least chance of magic compiler optimization"
for i in 1..3 do
F 3 4 i
printfn "Slightly better chance"
let Part = F 3 4
for i in 1..3 do
Part i
printfn "Now for real"
let F2 x y =
let tmp = Expensive x y
(fun z -> z + tmp)
printfn "Of course this still re-does it"
for i in 1..3 do
F2 3 4 i
printfn "Of course this finally saves re-do-ing Expensive"
let Opt = F2 3 4
for i in 1..3 do
Opt i
(* output
Least chance of magic compiler optimization
I am a side-effect of Expensive
I am a side-effect of Expensive
I am a side-effect of Expensive
Slightly better chance
I am a side-effect of Expensive
I am a side-effect of Expensive
I am a side-effect of Expensive
Now for real
Of course this still re-does it
I am a side-effect of Expensive
I am a side-effect of Expensive
I am a side-effect of Expensive
Of course this finally saves re-do-ing Expensive
I am a side-effect of Expensive
*)
Run Code Online (Sandbox Code Playgroud)
关键是,有关效果的语言语义要求编译器的行为与此完全相同,除非“昂贵”没有效果,并且编译器非常聪明并且可以自行发现这一点。