Per Møldrup-Dalum

Having fun with large integers and prime numbers

For quite some time I have wondered about why Mathematica (add link to article about my programming languages) is rather slow when it comes to integer factorization.

Tweet to @WolframResearch on the slowness of Mathematica for FactorInteger[]

A few years ago, one of my friends Thomas Egense implemented the bigmathfast Java library for working with large integers including integer factorization utilizing the PollardRho and ECM/Siqs algorithms. Back then, we created some large integers that were the product of two prime numbers, and then used the library to factorize them and comparing the results with PARI/GP and Mathematica. I also ran the tests in Julia and Maple, but I lost the results and none of them could compete with PARI/GP or `bigmathfast` nor were as slow as Mathematica.

I’ve now systematized this work and created a GitHub repository, Testing Prime Factorization, so it’s much easier to redo and extend.

Results

So, how fast or slow are PARI/GP and Mathematica now? I ran the benchmark suite on my MacBook M2 24GB RAM.

MacBook Air M2 24GB

Output columns are number of digits and run time measured in milliseconds. For Mathematica I stopped at 70 digits, as the calculation time became too long to wait for.

    >: wolframscript -version
    WolframScript 1.13.0 for Mac OS X ARM (64-bit)

    >: wolframscript -f factorize.wls large-ints-5.txt;echo "80   NA\n90   NA" > wls.out; cat wls.out
    30   19.692
    40   80.359
    50   1583.59
    60   17965.5
    70   377270.
    80    NA
    90    NA


     >: gp --version
                      GP/PARI CALCULATOR Version 2.17.2 (released)
             arm64 running darwin (aarch64/GMP-6.3.0 kernel) 64-bit version
         compiled: Feb 28 2025, Apple clang version 17.0.0 (clang-1700.3.19.1)
                               threading engine: pthread
                    (readline v8.3 disabled, extended help enabled)

    $ LARGE_INTS=large-ints-7.txt gp -q factorize.gp 2>/dev/null > gp.out; cat gp.out
    30	4
    40	18
    50	149
    60	1628
    70	11339
    80	270966
    90	3604437

    #bigmathfast-1.0-jar-with-dependencies.jar

    ./factorize-bigmathfast.py large-ints-7.txt > bmf.out; cat bmf.out
    30	64
    40	181
    50	965
    60	3654
    70	18411
    80	283088
    90	3503897
        

With the output in three data files, it can be compared against e.g., PARI/GP as the baseline.

     >: paste gp.out bmf.out wls.out|cut -f1,2,4,6| awk 'BEGIN {OFS="|"} NR<6 {print $1,$2/$2,$3/$2,$4/$2} NR>5 {print $1, $2/$2,$3/$2,"NA"}'|sed 's/^/|/;s/$/|/'|pbcopy
        
no. of digits PARI/GP bigmathfast Wolfram
301164.923
40110.05564.46439
5016.4765110.6281
6012.2444711.0353
7011.6236933.2719
8011.04474NA
9010.972107NA

PARI/GP is the baseline, and the numbers indicate how faster PARI/GP is. E.g., for a 30-digit integer, PARI/GP is 16 times faster than bigmathfast and 4.923 times faster than Wolfram. The relative slowness of bigmathfast for small integers is probably due to start-up time for the Java VM.

What did I learn?

Future Work