[racket-dev] Manual inlining destroys performance for this program

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Aug 22 11:05:46 EDT 2013

At Thu, 22 Aug 2013 10:59:35 -0400, Sam Tobin-Hochstadt wrote:
> This short program generates a lot of closures, and thus doesn't run very fast.
> #lang racket/base
> (require racket/flonum)
> (define (Point x0 x1 y0 y1)
>   (list (λ () (let ([x (- x1 x0)] [y (- y1 y0)])
>                 (flsqrt (+ (* x x) (* y y)))))))
> (define iter 1e4)
> (for ([i (in-range iter)])
>   (define p (Point (random) (random) (random) (random)))
>   (define f (car p))
>   (for ([i (in-range 1e3)])
>     (f)))
> I tried manually inlining `Point` by replacing `define` with
> `define-syntax-rule`, and the program gets about 8x *slower*.  I don't
> have any idea why this is happening, especially since `Point` is
> actually inlined by the optimizer in the `define` case.
> Any idea why this might be?

Using `define-syntax-rule' changes the program from

 (let ([x (random)])
   (call-a-lot (lambda () x)))


 (call-a-lot (lambda () (random)))

Did you mean to try

 (define (Point x0 x1 y0 y1)
   (let ([x (- x1 x0)] [y (- y1 y0)])
     (let ([v (flsqrt (+ (* x x) (* y y)))])
       (list (λ () v)))))


Posted on the dev mailing list.