如何根据优化教练的建议将 Racket 表达式更改为 Float 类型?

How to change Racket expression to Float type following Optimization Coach suggestion?

我正在使用 Typed Racket 编写一个小型数字程序。我想提高它的性能,并在 DrRacket 中安装了 Optimization Coach 插件。但是,我无法在它输出的第一个建议中遵循它的建议。

代码如下(可以在上下文中看到here in Github):

  (define:  : Positive-Integer 20)
  (define: base : Positive-Integer 10)
  (define: N : Integer (* (+ n ) (exact-floor (/ (log base) (log 2)))))

Optimization Coach 输出如下:

这看起来很简单吧? 2 可以更改为 2.0 并且这会产生优化(在线上的红色较少),但是 我不能触摸 base 没有得到 TypeCheck error.

base 定义或转换为 Float

  (define: base : Float 10.0)
  ;; or
  (log (cast base Float))

导致:

❯ raco exe bellard.rkt
bellard.rkt:31:47: Type Checker: type mismatch
  expected: Real
  given: Number
  in: (/ (log base) (log 2))

如何执行此优化?感谢您的帮助。

这有点傻,但我在 paper that presents Optimization Coach 中找到了我问题的答案,因为我太仓促了。

Unbeknownst to the programmer, however, this code suffers from a special case in Racket’s treatment of mixed-type arithmetic. Integer-float multiplication produces a floating point number, unless the integer is 0, in which case the result is the integer 0. Thus the result of the above multiplication is a floating-point number most of the time, but not always, making floating-point specialization unsafe

我想这也适用于混合类型分区,并将我的代码更改为:

(define: N : Integer (* (+ n ) (exact-floor (/ (log (exact->inexact base))
                                                (log 2.0)))))

插件用绿线确认优化。