Optimisation progress for libzahl, compared to other big integer libraries. These comparisons are for 152-bit integers. Functions in parenthesis the right column are functions that needs optimisation to improve the peformance of the function in the left column. Double-parenthesis means there may be a better way to do it. Inside square-brackets, there are some comments on multi-bit comparisons. zset .................... fastest [until ~750, then gmp, also tomsfastmath after ~2750] zseti ................... tomsfastmath is faster [always] zsetu ................... tomsfastmath is faster [always] zneg(a, b) .............. fastest [until ~300, then gmp] zneg(a, a) .............. fastest [always] (shared with gmp) zabs(a, b) .............. fastest [until ~700, then gmp, also after ~2700] zabs(a, a) .............. tomsfastmath is faster [always] zadd_unsigned ........... fastest [until 3600~4000, then gmp] (faster than all others' zadd) zsub_unsigned ........... fastest [always] (faster than all others' zsub) zadd .................... fastest [almost never] zsub .................... 98 % of libtommath [always] zand .................... 77 % of tomsfastmath [until ~150, then gmp] zor ..................... 65 % of tomsfastmath [until ~250, then gmp] zxor .................... 87 % of tomsfastmath [until ~500, then gmp] znot .................... fastest [always] zeven ................... fastest [always] zodd .................... fastest [always] zeven_nonzero ........... fastest [always] zodd_nonzero ............ fastest [always] zzero ................... fastest [always] (shared with gmp and libtommath) zsignum ................. fastest [always] (shared with gmp) zbits ................... fastest [always] zlsb .................... fastest [always] zswap ................... fastest [always] zlsh .................... fastest [until ~300, then gmp, also tomsfastmath after 2500~3200] zrsh .................... fastest [until ~150, then gmp, also tomsfastmath after 3000~4000] ztrunc(a, b, c) ......... fastest [until ~750, then gmp] ztrunc(a, a, b) ......... fastest [until ~150, then 77 % of tomsfastmath] zsplit .................. fastest [until 100~200, then gmp] zcmpmag ................. fastest [always] zcmp .................... fastest [almost never] zcmpi ................... fastest zcmpu ................... fastest zbset(a, b, 1) .......... fastest [until ~900, then gmp] zbset(a, a, 1) .......... fastest [always] zbset(a, b, 0) .......... fastest [until 600~150, then gmp, also tomsfastmath after ~3000] zbset(a, a, 0) .......... fastest [always] zbset(a, b, -1) ......... fastest [until ~1200, then gmp] zbset(a, a, -1) ......... fastest [always] zbtest .................. fastest [always] zgcd .................... 21 % of gmp (zcmpmag) zmul .................... slowest zsqr .................... slowest (zmul) zmodmul(big mod) ........ slowest ((zmul, zmod)) zmodsqr(big mod) ........ slowest ((zmul, zmod)) zmodmul(tiny mod) ....... slowest ((zmul)) zmodsqr(tiny mod) ....... slowest ((zmul)) zpow .................... slowest (zmul, zsqr) zpowu ................... slowest (zmul, zsqr) zmodpow ................. slowest (zmul, zsqr. zmod) zmodpowu ................ slowest (zmul, zsqr, zmod) zsets ................... 13 % of gmp zstr_length(a, 10) ...... gmp is faster [always] (zdiv, zsqr) zstr(a, b, n) ........... 8 % of gmp, 59 % of hebimath zrand(default uniform) .. 51 % of gmp zptest .................. slowest (zrand, zmodpow, zsqr, zmod) zsave ................... fastest [until ~600, then tomsfastmath; libtommath is suspicious] zload ................... fastest [always] zdiv(big denum) ......... tomsfastmath and naïve hebimath implementation are faster (zdivmod) zmod(big denum) ......... fastest (zdivmod) zdivmod(big denum) ...... fastest zdiv(tiny denum) ........ slowest zmod(tiny denum) ........ slowest zdivmod(tiny denum) ..... slowest Note, some corresponding functions are not implemented in some other libraries. In such cases, they have been implemented in the translation layers (found under bench/). Those implementations are often suboptimal, but probably in style with what you would write if you need that functionality. Note further, that if, for example, you want do perform addition and you know that your operands are non-negative, you would choose zadd_unsigned in libzahl, but if you are using a library that does not have the corrsponding function, you are better of with the regular addition (zadd). Also note, TomsFastMath does not support arbitrarily large integers, which gives is a significant performance advantage. Furthermore, no failure check is done with GMP. Additionally, hebimath has some functions that are not working correctly; those have been excluded from the comparison. Also note, NOT does not mean the same thing in all libraries, for example in GMP it means (-x - 1), thus, znot does not use GMP's NOT in the translations layer.