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
fractions.Fraction.__pow__ does unneeded renormalization #65335
Comments
The following Python runs unnecessarily slowly: import fractions
fractions.Fraction(6249919, 6250000) ** 89993 The problem here is that Fraction.__pow__ constructs a new Fraction() to return, and Fraction.__new__ tries to gcd to normalize the numerator/denominator. The gcd is very, very slow, and more to the point, unnecessary; raising a normalized fraction to an integer power will always yield another normalized fraction. fractions.Fraction.__pow__ should use this trick to make the code snippet above fast. |
This looks easily doable. |
LGTM. |
Hmm. Does this work correctly in the case |
Looks like it doesn't. How about adding a |
(And other operations like |
Thanks Mark, that is an excellent suggestion. |
LGTM. (For real this time :-). |
New changeset 91d7fadac271 by Mark Dickinson in branch 'default': |
Applied. I added an extra test for the |
Unfortunately, this introduced a bug. It seems Mark Dickinson should go easier on his LGTMs. :-) >>> import fractions
>>> fractions.Fraction(-1, 2) ** -1
Fraction(2, -1) That is a really strange object, since it's not normalized, and many functions expect all Fractions to be. For example, >>> _ == -2
False Of course, the easy fix would be to change line 52 of fractions.py to _normalize=True - but that would reintroduce the slowness talked about in the original message. Alternative fix would be to be careful about sign of the base, which might be messy if we intend to be completely general -- for example, in finite quotient rings, fractions don't have well-defined signs. [I'm not quite sure why the code in fractions.py is so general, maybe someone really wanted such a level of generality. I don't, so I'd be fine with this working only on int/int Fractions.] |
@vedran, the original issue is closed and the code for it already released. Please open a new issue referencing this one, otherwise your comments here will likely be forgotten. |
I now see Vedran has already opened bpo-27539 for this. Sorry for the additional noise. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: