]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91851: Micro optimizations for arithmetic between Fractions (#25518)
authorSergey B Kirpichev <skirpichev@gmail.com>
Sun, 8 Jan 2023 08:34:20 +0000 (11:34 +0300)
committerGitHub <noreply@github.com>
Sun, 8 Jan 2023 08:34:20 +0000 (00:34 -0800)
Adapted from
https://github.com/python/cpython/pull/24779/commits/046c84e8f9

This makes arithmetic between Fractions with small components
just as fast as before python/cpython#24779, at some expense of
mixed arithmetic (e.g. Fraction + int).

Lib/fractions.py
Misc/NEWS.d/next/Library/2022-04-23-08-12-14.gh-issue-91851.Jd47V6.rst [new file with mode: 0644]

index 939741115f91921486f794c6c1aa1b5621f7bd3c..bdba6c339593c230b04fb7042d7420f805d25398 100644 (file)
@@ -395,8 +395,10 @@ class Fraction(numbers.Rational):
 
         """
         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):
@@ -409,7 +411,7 @@ class Fraction(numbers.Rational):
         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):
@@ -491,8 +493,8 @@ class Fraction(numbers.Rational):
 
     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)
@@ -507,8 +509,8 @@ class Fraction(numbers.Rational):
 
     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)
@@ -523,8 +525,8 @@ class Fraction(numbers.Rational):
 
     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
@@ -540,8 +542,8 @@ class Fraction(numbers.Rational):
     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
diff --git a/Misc/NEWS.d/next/Library/2022-04-23-08-12-14.gh-issue-91851.Jd47V6.rst b/Misc/NEWS.d/next/Library/2022-04-23-08-12-14.gh-issue-91851.Jd47V6.rst
new file mode 100644 (file)
index 0000000..a918bff
--- /dev/null
@@ -0,0 +1 @@
+Optimize the :class:`~fractions.Fraction` arithmetics for small components.