Skip to content

Commit 046c84e

Browse files
committed
Use Fraction's private attributes in arithmetic methods
That's slightly faster for small components. Before: $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = F(6, 5)' 'a + b' 20000 loops, best of 11: 12.1 usec per loop $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = 7' 'a + b' 20000 loops, best of 11: 11.4 usec per loop After: $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = F(6, 5)' 'a + b' 50000 loops, best of 11: 9.74 usec per loop $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = 7' 'a + b' 20000 loops, best of 11: 16.5 usec per loop On the master: $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = F(6, 5)' 'a + b' 50000 loops, best of 11: 9.61 usec per loop $ ./python -m timeit -r11 -s 'from fractions import Fraction as F' \ -s 'a = F(10, 3)' -s 'b = 7' 'a + b' 50000 loops, best of 11: 9.11 usec per loop
1 parent 430e476 commit 046c84e

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

Lib/fractions.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,10 @@ class doesn't subclass a concrete type, there's no
355355
356356
"""
357357
def forward(a, b):
358-
if isinstance(b, (int, Fraction)):
358+
if isinstance(b, Fraction):
359359
return monomorphic_operator(a, b)
360+
elif isinstance(b, int):
361+
return monomorphic_operator(a, Fraction(b))
360362
elif isinstance(b, float):
361363
return fallback_operator(float(a), b)
362364
elif isinstance(b, complex):
@@ -367,9 +369,10 @@ def forward(a, b):
367369
forward.__doc__ = monomorphic_operator.__doc__
368370

369371
def reverse(b, a):
370-
if isinstance(a, numbers.Rational):
371-
# Includes ints.
372+
if isinstance(a, Fraction):
372373
return monomorphic_operator(a, b)
374+
elif isinstance(a, numbers.Integral):
375+
return monomorphic_operator(Fraction(a), b)
373376
elif isinstance(a, numbers.Real):
374377
return fallback_operator(float(a), float(b))
375378
elif isinstance(a, numbers.Complex):
@@ -444,8 +447,8 @@ def reverse(b, a):
444447
# common factors are removed by g1 == gcd(na, db).
445448

446449
def _add_sub_(a, b, pm=int.__add__):
447-
na, da = a.numerator, a.denominator
448-
nb, db = b.numerator, b.denominator
450+
na, da = a._numerator, a._denominator
451+
nb, db = b._numerator, b._denominator
449452
g = math.gcd(da, db)
450453
if g == 1:
451454
return Fraction(pm(na * db, da * nb), da * db, _normalize=False)
@@ -465,8 +468,8 @@ def _add_sub_(a, b, pm=int.__add__):
465468

466469
def _mul(a, b):
467470
"""a * b"""
468-
na, da = a.numerator, a.denominator
469-
nb, db = b.numerator, b.denominator
471+
na, da = a._numerator, a._denominator
472+
nb, db = b._numerator, b._denominator
470473
g1 = math.gcd(na, db)
471474
g2 = math.gcd(nb, da)
472475
return Fraction((na // g1) * (nb // g2),
@@ -477,8 +480,8 @@ def _mul(a, b):
477480
def _div(a, b):
478481
"""a / b"""
479482
# Same as _mul(), with inversed b.
480-
na, da = a.numerator, a.denominator
481-
nb, db = b.numerator, b.denominator
483+
na, da = a._numerator, a._denominator
484+
nb, db = b._numerator, b._denominator
482485
g1 = math.gcd(na, nb)
483486
g2 = math.gcd(db, da)
484487
n, d = (na // g1) * (db // g2), (nb // g1) * (da // g2)

0 commit comments

Comments
 (0)