From 6352009def94b37534a6213760b0b6c65f2cda40 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Dec 2019 08:04:09 -0600 Subject: [PATCH] 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 --- s/5_3.ss | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/s/5_3.ss b/s/5_3.ss index 0473addb0d..ae5746f768 100644 --- a/s/5_3.ss +++ b/s/5_3.ss @@ -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?)