# Python big integer vs. Julia big integer arithmetic

**URL:** https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777
**Category:** Performance
**Tags:** python
**Created:** [June 17, 2024, 9:39pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777 "2024-06-17T21:39:43Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![rfateman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfateman/32/22507_2.png) [@rfateman](https://discourse.julialang.org/u/rfateman)
#### Post date: [June 19, 2024, 3:00pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/22 "2024-06-19T15:00:09Z")

</div>

Here’s how one runs it from an interactive read-eval-print command loop in Maxima:

(%i14) **block([modulus:102], rat(3)^100000);**  
Warning: assigning 102, a non-prime, to ‘modulus’  
(%o14)/R/ 69

I have never personally run Maxima from a bash or windows command prompt, but I understand that it is possible by (essentially) sneaking stuff into the file that Maxima uses when it starts up (maxima.bat). In which case outputting to std might require using “print” or “format”… something like  
_command line prompt_ **maxima ? block([modulus:102], print(rat(3)^100000), exit())**;

Doing arithmetic modulo 102 which has factors 2, 3, 17 results in a warning,as shown above. I suppose that message would go to stdout or stderr if that is available, from a command line.  
If you really want to do bignum arithmetic, any Common Lisp will support that, and may use the highly-tuned GMP library available for different architectures.  
A reasonable Lisp program for powermod(n,power,modulus) would be a few lines of code, using about log\_2(power) multiplies and remainders.

In some Lisps, a newly-defined program is run interpretively but can be compiled on request. In other Lisps it is immediately compiled. Lisps allow, but do not require, type declarations and hints for optimization (like in-line expansion).  
I hope that some of the lessons from Common Lisp design and implementation have been considered by people implementing Julia.

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 4:16pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/23 "2024-06-19T16:16:44Z")

</div>

```julia
~ $ time maxima --very-quiet --batch-string=''

real	0m0.089s
user	0m0.079s
sys	0m0.017s
~ $ time julia -e ''

real	0m0.438s
user	0m0.421s
sys	0m0.140s
~ $ time maxima --very-quiet --batch-string='block([modulus:102], print(rat(3)^10000000000000), exit());'

block([modulus:102],print(rat(3)^10000000000000),exit())
warning: assigning 102, a non-prime, to 'modulus'
69 
                                    exit()

real	0m0.092s
user	0m0.077s
sys	0m0.022s
~ $ time julia -e 'println( powermod(3, 10000000000000, 102) )'
69

real	0m0.545s
user	0m0.552s
sys	0m0.116s

```

If I see it the right way **Julia could spawn Maxima on this one instead of itself to get the result faster** instead of calculating it by itself - or is there something wrong with this conclusion?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 19, 2024, 4:27pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/24 "2024-06-19T16:27:58Z")

</div>

> [@oOosys](#):
>
> If I see it the right way **Julia could spawn Maxima on this one instead of itself to get the result faster** instead of calculating it by itself - or is there something wrong with this conclusion?

Spawning `julia` is slow, so **spawning Julia to do a _single_ small arithmetic calculation** will be inefficient. If that’s how you want to use Julia, you are better off with `bc`.

That’s not how other people typically use, Julia, however—or, for that matter, how they use most other programming languages, including Python. They spawn Julia (or whatever program) _once_ and then do lots of calculations. For this pattern, tools like `@btime` and `timeit` are more useful and revealing, because they measure the **marginal cost** of a single small operation.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [June 19, 2024, 4:35pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/25 "2024-06-19T16:35:49Z")

</div>

```julia
~$ time julia -E 'sum(i for i in 1:2)'
3
user=0.49s system=0.08s cpu=390% total=0.144

```

Wow, Julia took 0.4s to add two numbers. That means if I ask it to add together 1000 numbers it should take ~8 minutes.

```julia
~$ time julia -E 'sum(i for i in 1:1000)'
500500
user=0.47s system=0.04s cpu=443% total=0.115

```

Huh, weird. It’s almost like `time` isn’t measuring the addition operation 🙃

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [June 19, 2024, 4:47pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/26 "2024-06-19T16:47:40Z")

</div>

Oh, and just for reference:

```julia
~$ time juliaclient -E 'powermod(3, 10000000000000, 102)'
69
user=0.00s system=0.00s cpu=0% total=0.073

```

where `juliaclient` is a tool that re-uses a Julia session I wrote. This is much better than `time julia ...`, and `@btime` is better again.

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 5:02pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/27 "2024-06-19T17:02:13Z")

</div>

> [@stevengj](#):
>
> They spawn Julia (or whatever program) _once_ and then do lots of calculations.

May you provide a code example which demonstrates that Julia will be faster considering the default use case you mention compared to Maxima? Just mentioning that the demonstrated timing is not representative would be much more expressive along with providing evidence, wouldn’t it?

Sorry … I have trouble with both, Julia and Maxima which are new to me, failing on constructing appropriate examples of code myself.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [June 19, 2024, 5:02pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/28 "2024-06-19T17:02:17Z")

</div>

> [@oOosys](#):
>
> If I see it the right way **Julia could spawn Maxima on this one instead of itself to get the result faster** instead of calculating it by itself

Then you would first spawn Julia, then spawn Maxima, and then Maxima would calculate powermod more slowly than Julia does (?).

That does not seem optimal.

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 5:04pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/29 "2024-06-19T17:04:35Z")

</div>

> [@DNF](#):
>
> Then you would first spawn Julia, then spawn Maxima, and then Maxima would calculate powermod more slowly than Julia does (?).
> 
> That does not seem optimal.

If I see it right Julia spawning Maxima and getting the result from Maxima will be in the total time still faster then letting Julia itself calculating it … or have I overseen something comparing the timings?

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [June 19, 2024, 5:12pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/30 "2024-06-19T17:12:14Z")

</div>

How would

spawning Julia + spawning Maxima + calculating powermod in Maxima

be faster than

spawning Julia + calculating powermod in Julia  
?

Would Julia compilation of powermod be that slow? Julia should be faster than Maxima, no?

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 5:17pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/31 "2024-06-19T17:17:58Z")

</div>

> [@DNF](#):
>
> Julia should be faster than Maxima, no?

From what I can see in the timings Julia time for performing the calculation minus the time for spawning Julia is in the order of 0.1 second, where time for performing the calculation including spawning Maxima is not much but still slightly less than that. And comparing the pure calculation time suggests that Maximal is an order of magnitude faster on this one. Or is there anything I have erroneously overseen here?

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [June 19, 2024, 5:19pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/32 "2024-06-19T17:19:07Z")

</div>

> [@tecosaur](#):
>
> ```julia
> ~$ time juliaclient -E 'powermod(3, 10000000000000, 102)'
> 69
> user=0.00s system=0.00s cpu=0% total=0.073
> 
> ```

\*cough

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [June 19, 2024, 5:20pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/33 "2024-06-19T17:20:52Z")

</div>

> [@oOosys](#):
>
> Or is there anything I have erroneously overseen here?

Yes, this is just extremely noisy, and likely to be off by orders of magnitude.

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 5:27pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/34 "2024-06-19T17:27:20Z")

</div>

> [@tecosaur](#):
>
> ```julia
> ~$ time juliaclient -E 'powermod(3, 10000000000000, 102)'
> 69
> user=0.00s system=0.00s cpu=0% total=0.073
> 
> ```

```julia
~ $ time juliaclient -E 'powermod(3, 10000000000000, 102)'
juliaclient: command not found

real	0m0.669s
user	0m0.149s
sys	0m0.031s

```

Sorry, I am not able to reproduce your result … any hints towards the reason for this?

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [June 19, 2024, 5:28pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/35 "2024-06-19T17:28:24Z")

</div>

> [@oOosys](#):
>
> Sorry, I am not able to reproduce your result … any hints towards the reason for this?

yes:

> [@tecosaur](#):
>
> where `juliaclient` is a tool that re-uses a Julia session I wrote.

---

<div class="post-metadata">

### Author: ![rfateman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfateman/32/22507_2.png) [@rfateman](https://discourse.julialang.org/u/rfateman)
#### Post date: [June 19, 2024, 5:39pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/36 "2024-06-19T17:39:57Z")

</div>

First of all, almost none of Maxima is being used. A Common Lisp system and one program could do this task. I think this program would work…  
(defun powermod(n pow mod)  
(cond((= pow 0) 1)  
((= pow 1)(rem n mod))  
((evenp pow)(powermod (rem (\* n n) mod) (ash pow -1)mod))  
(t (rem (\* n (powermod n (1- pow) mod)) mod))))  
[sorry, the indentation was removed by “discourse”.]

If you want to leave a Maxima or a Lisp client sitting around, that would eliminate most of the start-up time. It works for me.  
It seems to me that the routine “Oh, I just wrote a program in language X. I’ll have to start up an X-compiler-environment to run it” is turning the clock back 60 years, to pre-timesharing computing. It helps that computers are so much faster, and we don’t use punched cards… but  
read-eval-print loops and interactive computing has made me more productive, I think. If we are losing that, and today programmers edit some text interactively, and then essentially fire up a batch processing system… maybe start a browser, download an app on a phone, connect to a cloud…maybe use some elaborate deployment strategy… doesn’t seem like much fun. Oh well, times change.  
RJF

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [June 19, 2024, 5:44pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/37 "2024-06-19T17:44:07Z")

</div>

> [@oOosys](#):
>
> From what I can see in the timings Julia time for performing the calculation minus the time for spawning Julia is in the order of 0.1 second, where time for performing the calculation including spawning Maxima is not much but still slightly less than that. And comparing the pure calculation time suggests that Maximal is an order of magnitude faster on this one. Or is there anything I have erroneously overseen here?

Surely. Most of the functions you call in julia will be compiled the first time you call it. This goes for `powermod`, and for `run`, which you would use to spawn maxima. After `powermod` has been compiled, I’ve shown you elsewhere that the actual runtime for `powermod` is around 200 nanoseconds (it’s really just a few hundred cpu cycles). After `run` has been compiled (it might take longer than to compile `powermod`) it will take some milliseconds to start maxima.  
So using maxima to perform this calculation from julia would most likely take longer time.

Now, normally you don’t do just a single calculation. If you want to do, say, one million, it will take milliseconds with julia, and 10 minutes or so if you spawn maxima a million times.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [June 19, 2024, 5:57pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/38 "2024-06-19T17:57:03Z")

</div>

> [@tecosaur](#):
>
> ```julia
> ~$ time juliaclient -E 'powermod(3, 10000000000000, 102)'
> 69
> user=0.00s system=0.00s cpu=0% total=0.073
> 
> ```

I should probably mention since it won’t be clear, this comes from installing [GitHub - tecosaur/DaemonConductor.jl: Run many times, compile once.](https://github.com/tecosaur/DaemonConductor.jl) and running `DaemonConductor.install()` (linux only).

The result is that for things Julia does quickly, most of the time will actually be taken up by the socket initialisation, which takes a few ms.

```julia
~$ hyperfine -N "juliaclient -E 'powermod(3, 10000000000000, 102)'"
Benchmark 1: juliaclient -E 'powermod(3, 10000000000000, 102)'
  Time (mean ± σ): 5.3 ms ± 6.2 ms [User: 1.3 ms, System: 1.0 ms]
  Range (min … max): 4.3 ms … 84.3 ms 172 runs

```

---

<div class="post-metadata">

### Author: ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)
#### Post date: [June 19, 2024, 6:06pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/39 "2024-06-19T18:06:41Z")

</div>

> [@sgaure](#):
>
> Now, normally you don’t do just a single calculation. If you want to do, say, one million, it will take milliseconds with julia, and 10 minutes or so if you spawn maxima a million times.

This is an unfair comparison. Let’s start maxima once for the million times too to arrive at a fair one … Any code for such comparison?

---

<div class="post-metadata">

### Author: ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)
#### Post date: [June 19, 2024, 6:08pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/40 "2024-06-19T18:08:06Z")

</div>

@oOosys people already told you Julia is slow to start-up, sometimes compile, and fast to execute…that’s really all of it

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [June 19, 2024, 6:09pm UTC](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777/41 "2024-06-19T18:09:19Z")

</div>

> [@rfateman](#):
>
> [sorry, the indentation was removed by “discourse”.]

Wrap your code in triple backticks to get proper formatting and monospace font.

> [@rfateman](#):
>
> If we are losing that, and today programmers edit some text interactively, and then essentially fire up a batch processing system…

Using a REPL is the idiomatic way to use Julia. Starting Julia from the command line to run I small piece of code is contrary to that, I didn’t catch why the OP wants to do it.

[Previous page](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777.md?page=1)

[Next page](https://discourse.julialang.org/t/python-big-integer-vs-julia-big-integer-arithmetic/115777.md?page=3)
