
I have a question about Racket’s big integer implementation. I’m having a (overly long) discussion on the Julia slack about BigInt performance. In Julia’s case, a = a + b
results in allocating a new BigInt object, but doesn’t Racket do the same with (+ a b)
? In other words, we’re not making use of GMP’s mutating add!
function are we?

well, to be clear, (+ a b)
is not the same as a = a + b

Yes, to add context: function sum_n(m::BigInt, n::BigInt)::BigInt
val = BigInt(0)
i = BigInt(m)
one = BigInt(1)
while i <= n
val = val + i
i = i + one
end
val
end
and (define (sum-n m n [result 0])
(let loop ([ val 0 ][ i m ])
(if (<= i n)
(loop (+ val i) (+ i 1))
val)))

I suppose Racket could figure out it could do mpz_add(val, val, i)
, but I’d be a little surprised.

Actually, I’m not even sure if we’re using GMP, or whether Chez has a native implementation.

Chez Scheme does not use GMP, and it has its own implementation of bignum operations. Operations that produce a bignum will pretty much always have to allocate it. (But allocation is relatively fast in Chez Scheme.)

I’m curious how much may be impacted by your use of a while loop on the compiler (not SSA and may be difficult to prove certain stack allocation being overwritten with new ones allowing for the kind of optimization you’re looking for).
What’s your Julia timing of reduce(+, range(big"1",length=big"100000000000"))
?

(replacing the end w/ whatever upper-end you were using previously)

@massung your version takes ~ 8.5 sec, mine takes about 6.7 sec

I think BigInt manipulation dominates here.

From Matthew’s comment in a thread above, I think the difference may just come down to the difference in allocation & garbage collection overhead. Regardless, it’s good to see Racket shine here :)

Are you able to turn off gc in julia? At this point I’m just curious if GC is running more often in the loop than it needs to

I think I can. The @time
macro reported 24% time in GC.

Turning off GC knocks Julia down from 6.7 to 3.7 sec. Racket runs in 1.3 sec w/ GC enabled, or 2.0 sec w/ GC disabled, which is odd.

I’m on Racket CS 7.9

> Racket runs in 1.3 sec w/ GC enabled, or 2.0 sec w/ GC disabled :man-facepalming:

I was wondering about the situation with <https://github.com/racket/racket/issues/1647|Racket Issue 1647> (providing access to generics outside of struct
) and if there is any consensus on a resolution for it? A solution would significantly benefit my project, so I’m anxious to see the outcome.