#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.
This commit is contained in:
Georg Brandl 2014-09-24 08:37:55 +02:00
parent 02d39c24c4
commit 40f9735486
1 changed files with 17 additions and 7 deletions

View File

@ -104,7 +104,12 @@ class Fraction(numbers.Rational):
self = super(Fraction, cls).__new__(cls) self = super(Fraction, cls).__new__(cls)
if denominator is None: 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._numerator = numerator.numerator
self._denominator = numerator.denominator self._denominator = numerator.denominator
return self return self
@ -153,6 +158,9 @@ class Fraction(numbers.Rational):
raise TypeError("argument should be a string " raise TypeError("argument should be a string "
"or a Rational instance") "or a Rational instance")
elif type(numerator) is int is type(denominator):
pass # *very* normal case
elif (isinstance(numerator, numbers.Rational) and elif (isinstance(numerator, numbers.Rational) and
isinstance(denominator, numbers.Rational)): isinstance(denominator, numbers.Rational)):
numerator, denominator = ( numerator, denominator = (
@ -399,17 +407,17 @@ class Fraction(numbers.Rational):
def _add(a, b): def _add(a, b):
"""a + b""" """a + b"""
return Fraction(a.numerator * b.denominator + da, db = a.denominator, b.denominator
b.numerator * a.denominator, return Fraction(a.numerator * db + b.numerator * da,
a.denominator * b.denominator) da * db)
__add__, __radd__ = _operator_fallbacks(_add, operator.add) __add__, __radd__ = _operator_fallbacks(_add, operator.add)
def _sub(a, b): def _sub(a, b):
"""a - b""" """a - b"""
return Fraction(a.numerator * b.denominator - da, db = a.denominator, b.denominator
b.numerator * a.denominator, return Fraction(a.numerator * db - b.numerator * da,
a.denominator * b.denominator) da * db)
__sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
@ -561,6 +569,8 @@ class Fraction(numbers.Rational):
def __eq__(a, b): def __eq__(a, b):
"""a == b""" """a == b"""
if type(b) is int:
return a._numerator == b and a._denominator == 1
if isinstance(b, numbers.Rational): if isinstance(b, numbers.Rational):
return (a._numerator == b.numerator and return (a._numerator == b.numerator and
a._denominator == b.denominator) a._denominator == b.denominator)