如何优化这条Racket代码?

Sal*_*Egg 5 optimization sbcl racket typed-racket

我想计算1 + 1/2 + 1/3 + ... + 1/100000000的总和(使用双浮点数).

使用SBCL,此代码的运行速度与C中一样快:

(loop for i fixnum from 1 to 100000000 sum (/ 1.0d0 i) double-float)
Run Code Online (Sandbox Code Playgroud)

如何在Typed Racket中优化此代码?我试过了

#lang typed/racket

(define: (test) : Float
         (for/fold: : Float
                    ([s : Float 0.0])
                    ([i : Fixnum (in-range 1 100000001)])
                    (+ s (/ 1.0 i))))

(time (test))
Run Code Online (Sandbox Code Playgroud)

此代码仅比无类型代码快一点.我可以走得更远吗?

Asu*_*awa 7

如果像Greg建议的那样运行优化教练,它会立即告诉你循环体很慢,因为/函数正在进行混合算术(在fixnum和flonum上).如果你插入一个(fx->fl i)代替i它的速度更快(接近2倍在我的机器上).

此外,如果您在DrRacket中计时,您将需要使用racket可执行文件计时.DrRacket添加了在开发过程中有用的调试工具,但不适合时序.

  • 使用`exact-> inexact`或`unsafe-fx-> fl`而不是`fx-> fl`可以提供另外~30%的加速,因为它省略了检查参数实际上是一个fixnum. (4认同)
  • 此外,一些初步基准测试表明,该程序的优化Typed Racket代码比SBCL快约10%. (4认同)