Skip to content

Commit

Permalink
gh-91851: Micro optimizations for arithmetic between Fractions (#25518)
Browse files Browse the repository at this point in the history
Adapted from
046c84e8f9

This makes arithmetic between Fractions with small components
just as fast as before #24779, at some expense of
mixed arithmetic (e.g. Fraction + int).
  • Loading branch information
skirpichev authored Jan 8, 2023
1 parent 6d3bc4a commit 909982e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
22 changes: 12 additions & 10 deletions Lib/fractions.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,10 @@ class doesn't subclass a concrete type, there's no
"""
def forward(a, b):
if isinstance(b, (int, Fraction)):
if isinstance(b, Fraction):
return monomorphic_operator(a, b)
elif isinstance(b, int):
return monomorphic_operator(a, Fraction(b))
elif isinstance(b, float):
return fallback_operator(float(a), b)
elif isinstance(b, complex):
Expand All @@ -409,7 +411,7 @@ def forward(a, b):
def reverse(b, a):
if isinstance(a, numbers.Rational):
# Includes ints.
return monomorphic_operator(a, b)
return monomorphic_operator(Fraction(a), b)
elif isinstance(a, numbers.Real):
return fallback_operator(float(a), float(b))
elif isinstance(a, numbers.Complex):
Expand Down Expand Up @@ -491,8 +493,8 @@ def reverse(b, a):

def _add(a, b):
"""a + b"""
na, da = a.numerator, a.denominator
nb, db = b.numerator, b.denominator
na, da = a._numerator, a._denominator
nb, db = b._numerator, b._denominator
g = math.gcd(da, db)
if g == 1:
return Fraction(na * db + da * nb, da * db, _normalize=False)
Expand All @@ -507,8 +509,8 @@ def _add(a, b):

def _sub(a, b):
"""a - b"""
na, da = a.numerator, a.denominator
nb, db = b.numerator, b.denominator
na, da = a._numerator, a._denominator
nb, db = b._numerator, b._denominator
g = math.gcd(da, db)
if g == 1:
return Fraction(na * db - da * nb, da * db, _normalize=False)
Expand All @@ -523,8 +525,8 @@ def _sub(a, b):

def _mul(a, b):
"""a * b"""
na, da = a.numerator, a.denominator
nb, db = b.numerator, b.denominator
na, da = a._numerator, a._denominator
nb, db = b._numerator, b._denominator
g1 = math.gcd(na, db)
if g1 > 1:
na //= g1
Expand All @@ -540,8 +542,8 @@ def _mul(a, b):
def _div(a, b):
"""a / b"""
# Same as _mul(), with inversed b.
na, da = a.numerator, a.denominator
nb, db = b.numerator, b.denominator
na, da = a._numerator, a._denominator
nb, db = b._numerator, b._denominator
g1 = math.gcd(na, nb)
if g1 > 1:
na //= g1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Optimize the :class:`~fractions.Fraction` arithmetics for small components.

0 comments on commit 909982e

Please sign in to comment.