Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
gh-72902: speedup Fraction.from_decimal/float in typical cases#133251
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 ourterms of service andprivacy 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
Here patch2 is the current version. v1 had a hack to check # bench.pyimportpyperffromfractionsimportFractionasFfromdecimalimportDecimalasDfromnumbersimportIntegralrunner=pyperf.Runner()s='Fraction.from_decimal'f=F.from_decimalclassmyint:numerator=123denominator=1def__int__(self):return123def__repr__(self):return"myint"Integral.register(myint)forvin [1,myint(),D(1)]:r=s+'('+repr(v)+')'runner.bench_func(r,f,v)s='Fraction.from_float'f=F.from_floatforvin [1,myint(),1.1]:r=s+'('+repr(v)+')'runner.bench_func(r,f,v) diff --git a/Lib/fractions.py b/Lib/fractions.pyindex fa722589fb..d7887af9f8 100644--- a/Lib/fractions.py+++ b/Lib/fractions.py@@ -335,23 +335,23 @@ def from_float(cls, f): Beware that Fraction.from_float(0.3) != Fraction(3, 10). """- if isinstance(f, numbers.Integral):+ if not isinstance(f, float):+ if not isinstance(f, (int, numbers.Integral)):+ raise TypeError("%s.from_float() only takes floats, not %r (%s)" %+ (cls.__name__, f, type(f).__name__)) return cls(f)- elif not isinstance(f, float):- raise TypeError("%s.from_float() only takes floats, not %r (%s)" %- (cls.__name__, f, type(f).__name__)) return cls._from_coprime_ints(*f.as_integer_ratio()) @classmethod def from_decimal(cls, dec): """Converts a finite Decimal instance to a rational number, exactly.""" from decimal import Decimal- if isinstance(dec, numbers.Integral):- dec = Decimal(int(dec))- elif not isinstance(dec, Decimal):- raise TypeError(- "%s.from_decimal() only takes Decimals, not %r (%s)" %- (cls.__name__, dec, type(dec).__name__))+ if not isinstance(dec, Decimal):+ if not isinstance(dec, (int, numbers.Integral)):+ raise TypeError(+ "%s.from_decimal() only takes Decimals, not %r (%s)" %+ (cls.__name__, dec, type(dec).__name__))+ dec = int(dec) return cls._from_coprime_ints(*dec.as_integer_ratio()) @classmethod |
This is a second part of improvements, cherry-picked from the issue thread. I think this is less controversial, as speedup affects main use-cases (i.e. Decimal's or float's, respectively). With v2 version we haven't speed regressions for integer case. Though, I'm not sure about using that hack. |
neonene commentedMay 17, 2025 • edited by skirpichev
Loading Uh oh!
There was an error while loading.Please reload this page.
edited by skirpichev
Uh oh!
There was an error while loading.Please reload this page.
This is slightly slower:
|
Uh oh!
There was an error while loading.Please reload this page.