OK, data is good. Here is what Gambit expands your code to, with some annotations: heine:~/Downloads> gsc -c -expansion conversion.scm Expansion: (define noop (lambda () #!void)) The following implies that gsc could expand (floor n) better as: (cond ((fixnum? n) n) ((and ('#<procedure #2 ##flonum?> n) ('#<procedure #3 ##flfinite?> n))('#<procedure #4 ##flfloor> n)) (else('#<procedure #5 floor> n)))) and it could expand inexact->exact better (after defining flfixnum?) as (cond ((fixnum? n) n) ((and (flonum? n) (flinteger? n)(flfixnum? n)) (flonum->fixnum n)) (else (<inexact->exact> n)) (define ->integer (lambda (n) (lambda () (let ((temp.5 (if (and ('#<procedure #2 ##flonum?> n) ('#<procedure #3 ##flfinite?> n)) ('#<procedure #4 ##flfloor> n) ('#<procedure #5 floor> n)))) (if ('#<procedure #6 ##fixnum?> temp.5) temp.5 ('#<procedure #7 inexact->exact> temp.5)))))) (define ->flonum (lambda (n) (lambda () (if ('#<procedure #6 ##fixnum?> n) ('#<procedure #8 ##fl<-fx> n) (if ('#<procedure #2 ##flonum?> n) n ('#<procedure #9 exact->inexact> n)))))) This following machinery seems pretty heavy. I'd suggest (define (test t #!optional (seconds 1.)) (let loop ((n 1)) (let ((start-time (cpu-time))) (do ((i 0 (fx+ i 1))) ((fx= i n)) (t)) (let ((end-time (cpu-time))) (if (<= seconds (fl- end-time start-time)) (pp (/ n (fl- end-time start-time))) (loop (fx* n 2))))))) (define test (lambda (t #!optional (seconds 5)) (let ((at ('#<procedure #10 ##box> 0))) (let ((th (thread-start! (make-thread (lambda () (letrec ((loop (lambda (t at) (let ((begin-temp.1 (t))) (let ((begin-temp.0 ('#<procedure #11 ##set-box!> at (let ((temp.7 ('#<procedure #12 ##unbox> at))) (if ('#<procedure #6 ##fixnum?> temp.7) (let ((temp.9 ('#<procedure #13 ##fx+?> temp.7 1))) (if temp.9 temp.9 ('#<procedure #14 fx+> temp.7 1))) ('#<procedure #14 fx+> temp.7 1)))))) (loop t at)))))) (loop t at))))))) (let ((begin-temp.3 (thread-sleep! seconds))) (let ((r ('#<procedure #12 ##unbox> at))) (let ((begin-temp.2 (thread-terminate! th))) (let ((temp.12 (if (and ('#<procedure #2 ##flonum?> seconds) ('#<procedure #2 ##flonum?> r)) ('#<procedure #15 ##fl/> r seconds) ('#<procedure #16 /> r seconds)))) (if ('#<procedure #6 ##fixnum?> temp.12) ('#<procedure #8 ##fl<-fx> temp.12) (if ('#<procedure #2 ##flonum?> temp.12) temp.12 ('#<procedure #9 exact->inexact> temp.12))))))))))) With that, my rates are (first for void, then the four ->integer, then the four ->flonum): 76082403.02475469 18077766.69130593 2113932.395354323 12632656.242117403 1560283.434666285 34377410.006859235 69323006.15509051 1230645.7282318561 69180045.37858963 And, with (declare (not safe)) I get 105510445.88390666 18807367.927219782 2444080.701261633 13230418.609566122 1569627.036643679 47124065.98183112 92942772.26488659 1327228.230636181 92942772.26488681