Opened 5 years ago

Last modified 5 years ago

#1620 closed defect

Some let bindings are not replaced resulting in unnecessary CPS calls — at Version 1

Reported by: sjamaan Owned by:
Priority: major Milestone: 5.2
Component: compiler Version: 5.0.0
Keywords: Cc:
Estimated difficulty: hard

Description (last modified by sjamaan)

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 "C_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.

Change History (1)

comment:1 Changed 5 years ago by sjamaan

Description: modified (diff)
Note: See TracTickets for help on using tickets.