-
Notifications
You must be signed in to change notification settings - Fork 34
Faster fmpz/int conversion using from_bytes/to_bytes #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
c7ded0c to
f349183
Compare
|
The function |
|
Since this PR seems to give performance on par with Also, it should work with older Python versions. |
|
The PEP 757 interface is provided as CPython's best effort to give something efficient for this using public API in Python 3.14 onwards. I think that should be the baseline before trying any other approach. |
|
Interesting, conversion to int seems asymptotically faster with this approach (c.f. using mpz_export). Perhaps, it could be a little better with new
No, gmpy2 uses PEP 757 API (using pythoncapi-compat for <3.14). Import (int -> mpz)
Export (mpz -> int)
Could someone trigger CI tests in this pr (build logs are expired)? benchmark scripts# bench-import.py
import os
import pyperf
_T = os.getenv('_T')
if _T == "gmpy2.mpz":
from gmpy2 import mpz
elif _T == "gmp.mpz":
from gmp import mpz
else:
from flint import fmpz as mpz
cases = ['1<<7', '1<<38', '1<<300', '1<<3000', '1<<10000']
runner = pyperf.Runner()
for c in cases:
i = eval(c)
runner.bench_func(c, mpz, i)# bench-export.py
import os
import pyperf
_T = os.getenv('_T')
if _T == "gmpy2.mpz":
from gmpy2 import mpz
elif _T == "gmp.mpz":
from gmp import mpz
else:
from flint import fmpz as mpz
cases = ['1<<7', '1<<38', '1<<300', '1<<3000', '1<<10000']
runner = pyperf.Runner()
for c in cases:
i = eval(c)
m = mpz(i)
runner.bench_func(c, int, m) |
I think that python-flint should do the same. |
This is a proposal to handle issue #159 for Python versions below 3.14 (for example Ubuntu 24.04 LTS uses Python 3.12).
The idea is to use standard int methods (
from_bytes,to_bytes) to obtain a binary serialization, then cast the byte array to ulong.Special care is needed for big-endian platforms, however I am unable to test whether the patch proposal is correct for big-endian platforms. Let me know what would be the preferred approach.
Benchmarks done using
%timeitin iPython with Python 3.13AFAIK gmpy2 uses private Python stuff already so it might be difficult to do better.
(edited for changes in commit f349183 for negative numbers)