Skip to content
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

gh-102471: convert decimal module to use import/export API for ints (PEP 757) #127925

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

skirpichev
Copy link
Member

@skirpichev skirpichev commented Dec 13, 2024

Benchmark ref patch
Decimal(1<<7) 674 ns 735 ns: 1.09x slower
Decimal(1<<38) 768 ns 731 ns: 1.05x faster
Decimal(1<<300) 1.89 us 2.01 us: 1.06x slower
Decimal(1<<3000) 90.2 us 90.7 us: 1.01x slower
int(Decimal(1<<7)) 610 ns 531 ns: 1.15x faster
int(Decimal(1<<38)) 696 ns 522 ns: 1.33x faster
int(Decimal(1<<3000)) 116 us 117 us: 1.01x slower
Geometric mean (ref) 1.04x faster

Benchmark hidden because not significant (1): int(Decimal(1<<300))

bench.py
import pyperf
from decimal import Decimal as D

runner = pyperf.Runner()
runner.bench_func('Decimal(1<<7)', D, 1 << 7)
runner.bench_func('Decimal(1<<38)', D, 1 << 38)
runner.bench_func('Decimal(1<<300)', D, 1 << 300)
runner.bench_func('Decimal(1<<3000)', D, 1 << 3000)

runner.bench_func('int(Decimal(1<<7))', int, D(1 << 7))
runner.bench_func('int(Decimal(1<<38))', int, D(1 << 38))
runner.bench_func('int(Decimal(1<<300))', int, D(1 << 300))
runner.bench_func('int(Decimal(1<<3000))', int, D(1 << 3000))

@picnixz
Copy link
Contributor

picnixz commented Dec 13, 2024

hide _PyLong_FromDigits()? it's not used outside of the longobject.c anymore

Let's not hide this. Maybe someone is using it (it was removed then restored IIRC).

news

Not needed I think, unless you want to indicate the performance gain (it's always nice to know that something is faster). I did report the improvements of fnmatch.translate, so I think you can report those improvements as well.

n = (mpd_sizeinbase(x, 2) + bpd - 1) / bpd;
PyLongWriter *writer = PyLongWriter_Create(mpd_isnegative(x), n,
(void**)&ob_digit);
/* mpd_sizeinbase can overestimate size by 1 digit, set it to zero. */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, this looks as a bug in the mpdecimal. C.f. the GNU GMP, the mpz_sizeinbase docs says: "If base is a power of 2, the result is always exact".

@skirpichev
Copy link
Member Author

Let's not hide this. Maybe someone is using it (it was removed then restored IIRC).

I've updated the pr descriptions with my research. So far, I've found just one use case.

At least, I think we should deprecate (not soft) this. This apparently affects not so much projects and there is now a public alternative. @picnixz, what do you think?

@skirpichev skirpichev marked this pull request as ready for review December 14, 2024 01:05
@picnixz
Copy link
Contributor

picnixz commented Dec 14, 2024

At least, I think we should deprecate (not soft) this

I would be fine with deprecating it, saying which alternative to use, so that we can simply remove it in some later versions. I think Victor was the one who removed and restored it so we should ask him as well.

@picnixz
Copy link
Contributor

picnixz commented Dec 14, 2024

should dec_from_long() be modified here? (To use the PyLong_Export API.) I would prefer to do this in a separate PR.

If you prefer doing it in a follow-up PR because you fear it would be too hard to review, then it's better. If the change is minimal, we can do it this one (I didn't check the code to change)

@skirpichev
Copy link
Member Author

If the change is minimal, we can do it this one

You can estimate them looking on the gmpy2 pr (referenced in the PEP): aleaxit/gmpy#495 In principle, I don't think that this will complicate review to much. On another hand, changes looks logically independent. I would rather include here deprecation.

@picnixz
Copy link
Contributor

picnixz commented Dec 14, 2024

  • Let's change dec_from_long in another PR since the changes are independent (sorry it's 3 AM here and I don't have much energy).
  • For deprecating _PyLong_FromDigits, maybe it's better to make a separate PR so that we have a dedicated NEWS entry and re-use the issue that actually removed the private API (and not the issue that reverted the removal). WDYT? (we would also be able to change PyLong_Copy accordingly)

@skirpichev

This comment was marked as outdated.

@skirpichev skirpichev marked this pull request as draft December 14, 2024 05:07
@skirpichev skirpichev changed the title gh-102471: convert decimal module to use PyLongWriter API (PEP 757) gh-102471: convert decimal module to use import/export API for ints (PEP 757) Dec 14, 2024
@skirpichev skirpichev requested a review from picnixz December 14, 2024 06:53
@skirpichev skirpichev marked this pull request as ready for review December 14, 2024 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants