Opened 6 years ago
Last modified 5 years ago
#1620 closed defect
Some let bindings are not replaced resulting in unnecessary CPS calls — at Initial Version
Reported by: | sjamaan | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 5.2 |
Component: | compiler | Version: | 5.0.0 |
Keywords: | Cc: | ||
Estimated difficulty: | hard |
Description
We've seen in #1604 that this is a performance killer:
This code is fast when compiled with -O5 -strict-types -fixnum-arithmetic
:
(define (fib n) (if (or (eq? n 0) (eq? n 1)) n (+ (fib (- n 1)) (fib (- n 2))))) (let loop ((n 0)) (when (< n 35) (print "n=" n " => " (fib n)) (loop (+ n 1))))
This code is slow when compiled with the same options, even though the generated intermediate Scheme code is equivalent:
(define (fib n) (if (or (= n 0) (= n 1)) n (+ (fib (- n 1)) (fib (- n 2))))) (let loop ((n 0)) (when (< n 35) (print "n=" n " => " (fib n)) (loop (+ n 1))))
The reason is that in the first case, the eq?
calls get replaced by (##core#inline "eqp" a b)
while in the second case, the =
calls get replaced by (let ((x a) (y b)) (##core_inline "C_eqp" x y))
and the let
is not considered replacable
even though (I think?) it should be.
That's because fib
's arguments are marked by analyze-expression
in core.scm
as captured
.
Fixing this could potentially make a lot of code a lot faster! We definitely should run the benchmarks with and without the fix to find out how dramatic the improvement is.