sometimes-faster fixnum / via quotient

Try `fxquotient` with a `fx*` check to implement `/` on fixnums.
That's fast enough to be much faster when it works, and only slows
down a more general `/` a little.

original commit: e91430be9b71f4913965db688a15f6d7206b38f3
This commit is contained in:
Matthew Flatt 2019-12-25 08:04:09 -06:00
parent 29abe3e317
commit 6352009def

View File

@ -2211,9 +2211,20 @@
(set! $/
(lambda (who x y)
(type-case y
[(fixnum? bignum?)
[(fixnum?)
(type-case x
[(fixnum? bignum?)
[(fixnum?)
;; Trying `fxquotient` followed by a `fx*` check
;; is so much faster (in the case that it works)
;; that it's worth a try
(when (eq? y 0) (domain-error who y))
(if (fx= x (constant most-negative-fixnum))
(integer/ x y) ; in case `y` is -1
(let ([q (fxquotient x y)])
(if (fx= x (fx* y q))
q
(integer/ x y))))]
[(bignum?)
(when (eq? y 0) (domain-error who y))
(integer/ x y)]
[(ratnum?)
@ -2226,6 +2237,18 @@
(make-rectangular (/ (real-part x) y) (/ (imag-part x) y))]
[(flonum?) (inexact-exact/ x y)]
[else (nonnumber-error who x)])]
[(bignum?)
(type-case x
[(fixnum? bignum?)
(integer/ x y)]
[(ratnum?)
(/ ($ratio-numerator x) (* y ($ratio-denominator x)))]
[($exactnum?)
(make-rectangular (/ (real-part x) y) (/ (imag-part x) y))]
[($inexactnum?)
(make-rectangular (/ (real-part x) y) (/ (imag-part x) y))]
[(flonum?) (inexact-exact/ x y)]
[else (nonnumber-error who x)])]
[(ratnum?)
(type-case x
[(fixnum? bignum?)