Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Right now we just use__new__() with a private kwarg_normalize=False. That's slightly less efficient, then a dedicated class method.
POC patch
diff --git a/Lib/fractions.py b/Lib/fractions.pyindex 49a3f2841a..27c75785fb 100644--- a/Lib/fractions.py+++ b/Lib/fractions.py@@ -315,6 +315,13 @@ def from_decimal(cls, dec): (cls.__name__, dec, type(dec).__name__)) return cls(*dec.as_integer_ratio())+ @classmethod+ def _from_pair(cls, num, den):+ obj = super(Fraction, cls).__new__(cls)+ obj._numerator = num+ obj._denominator = den+ return obj+ def is_integer(self): """Return True if the Fraction is an integer.""" return self._denominator == 1@@ -703,13 +710,13 @@ def _add(a, b): nb, db = b._numerator, b._denominator g = math.gcd(da, db) if g == 1:- return Fraction(na * db + da * nb, da * db, _normalize=False)+ return Fraction._from_pair(na * db + da * nb, da * db) s = da // g t = na * (db // g) + nb * s g2 = math.gcd(t, g) if g2 == 1:- return Fraction(t, s * db, _normalize=False)- return Fraction(t // g2, s * (db // g2), _normalize=False)+ return Fraction._from_pair(t, s * db)+ return Fraction._from_pair(t // g2, s * (db // g2)) __add__, __radd__ = _operator_fallbacks(_add, operator.add)
We can drop private kwarg of__new__() after adopting this way.
Some benchmarks
With above patch
$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7),Q(5, 8)' -u usec 'a+b'50000 loops, best of 5: 4.4 usec per loop$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7)**100,Q(5, 8)**100' -u usec 'a+b'20000 loops, best of 5: 12.6 usec per loopOn themastermain:
$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7),Q(5, 8)' -u usec 'a+b'50000 loops, best of 5: 6.99 usec per loop$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7)**100,Q(5, 8)**100' -u usec 'a+b'20000 loops, best of 5: 15.9 usec per loop