Closed jpellegrini closed 1 year ago
I think this can be enhanced:
int_quotient
could be replaced by integer_division
since integer_division
now can be asked to only return the quotientinteger_division
can be a bit more clearI'll change this PR soon
Ok - I have made a better version of it. It's clearer.
I have also simplified int_quotient
so it uses one less mpz_t
variable, and calls mpz_clear
on exit.
This one is ready.
By the way - the timings in the commit message have been updated - the new version seems better than the first one I had submitted in the PR.
(I thought I'd use the new int_divide
to replace int_quotient
for making new rationals, but it wasn't worth it)
And the really nice speedup happens when we divide a fixnum by a bignum:
(let ((big (+ (expt 2 70) 3))
(fix 10010192)
(a 1))
(time
(repeat 10_000_000
(set! a (remainder fix big))))
a)
current code: 3258.373 ms
this patch: 762.4 ms
(let ((big (+ (expt 2 70) 3))
(fix 10010192)
(a 1))
(time
(repeat 10_000_000
(set! a (quotient fix big))))
a)
current code: 3306.894 ms
this patch: 776.137 ms
Ok, so I included some more commits related to integer division, including a considerable speedup to round
(the idea is to do integer division, then just check if abs(remainder) / 2
is past the midpoint of all possible remainders.
All tests pass. I'm not sure there is more to include in this PR -- I believe it's ready.
Hello @jpellegrini,
I have merged this PR. The enhancement is really impressive :+1: . For fixnum operations, you had similar performance with and without the patch. On my laptop, (an old i5), these operations were 10% slower with the patch. I have finally added a fast path in integer-division
when arguments are both fixnums (without any conversion) and the code is now faster than before also in this case (which is probably the more frequent).
Thanks a lot for this contribution.
Both the GMP and the mini-GMP have functions to extract only the quotient and only the remainder from a division. We change
integer_division
so that if either ofquotient
orremainder
isNULL
, then it is not used, and a faster GMP function is called for bignums.We also do the same for fixnums and doubles, for consistency and simplicity (so as not to treat bignums in a separate function), although there doesn't seem to be much of a speedup for fixnums.
TIMINGS
Ten runs of each, the time reported is the average.
Bignums
Flonums
Fixnums
Odd?
andeven?
for flonumsInterestingly, this one get really faster: