# [Python-checkins] cpython: #22464: Speed up common Fraction operations by special-casing several

georg.brandl python-checkins at python.org
Wed Sep 24 08:40:44 CEST 2014

```https://hg.python.org/cpython/rev/646bc7d3544b
changeset:   92554:646bc7d3544b
user:        Georg Brandl <georg at python.org>
date:        Wed Sep 24 08:37:55 2014 +0200
summary:
#22464: Speed up common Fraction operations by special-casing several
operations for int-type arguments: constructor and equality test.

Also avoid redundant property lookups in addition and subtraction.

files:
Lib/fractions.py |  24 +++++++++++++++++-------
1 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/Lib/fractions.py b/Lib/fractions.py
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -104,7 +104,12 @@
self = super(Fraction, cls).__new__(cls)

if denominator is None:
-            if isinstance(numerator, numbers.Rational):
+            if type(numerator) is int:
+                self._numerator = numerator
+                self._denominator = 1
+                return self
+
+            elif isinstance(numerator, numbers.Rational):
self._numerator = numerator.numerator
self._denominator = numerator.denominator
return self
@@ -153,6 +158,9 @@
raise TypeError("argument should be a string "
"or a Rational instance")

+        elif type(numerator) is int is type(denominator):
+            pass  # *very* normal case
+
elif (isinstance(numerator, numbers.Rational) and
isinstance(denominator, numbers.Rational)):
numerator, denominator = (
@@ -399,17 +407,17 @@

"""a + b"""
-        return Fraction(a.numerator * b.denominator +
-                        b.numerator * a.denominator,
-                        a.denominator * b.denominator)
+        da, db = a.denominator, b.denominator
+        return Fraction(a.numerator * db + b.numerator * da,
+                        da * db)

def _sub(a, b):
"""a - b"""
-        return Fraction(a.numerator * b.denominator -
-                        b.numerator * a.denominator,
-                        a.denominator * b.denominator)
+        da, db = a.denominator, b.denominator
+        return Fraction(a.numerator * db - b.numerator * da,
+                        da * db)

__sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)

@@ -561,6 +569,8 @@

def __eq__(a, b):
"""a == b"""
+        if type(b) is int:
+            return a._numerator == b and a._denominator == 1
if isinstance(b, numbers.Rational):
return (a._numerator == b.numerator and
a._denominator == b.denominator)

--
Repository URL: https://hg.python.org/cpython
```