Skip to content

Optimize mixed-mode operations with small int's #231

@skirpichev

Description

@skirpichev

Consider following benchmark, which not uses integer literals during computation:

collatz0.py
# collatz0.py
import pyperf
from gmp import mpz
#from gmpy2 import mpz

zero = mpz(0)
one = mpz(1)
two = mpz(2)
three = mpz(3)

# https://en.wikipedia.org/wiki/Collatz_conjecture
def collatz(n):
    total = 0
    n = mpz(n)
    while n > one:
        n = n*three + one if n & one else n//two
        total += 1
    return total

runner = pyperf.Runner()
for i in [97, 871]:
    h = f"collatz({i})"
    runner.bench_func(h, collatz, i)
Benchmark gmpy2.mpz gmp.mpz
collatz(97) 94.5 us 84.7 us: 1.12x faster
collatz(871) 141 us 127 us: 1.11x faster
Geometric mean (ref) 1.11x faster

But with integer literals in code - things are much worse:

collatz1.py
import pyperf
#from gmp import mpz
from gmpy2 import mpz

# https://en.wikipedia.org/wiki/Collatz_conjecture
def collatz(n):
    total = 0
    n = mpz(n)
    while n > 1:
        n = n*3 + 1 if n & 1 else n//2
        total += 1
    return total

runner = pyperf.Runner()
for i in [97, 871]:
    h = f"collatz({i})"
    runner.bench_func(h, collatz, i)
Benchmark gmpy2.mpz gmp.mpz
collatz(97) 91.7 us 151 us: 1.64x slower
collatz(871) 138 us 225 us: 1.64x slower
Geometric mean (ref) 1.64x slower

This may depend on diofant/zz#3, but clearly does make sense alone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions