mirror of https://github.com/python/cpython
Performance optimizations on Fraction's constructor.
./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3)` 31.7 usec/loop -> 9.2 usec/loop ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3, 2)'` 27.7 usec/loop -> 9.32 usec/loop ./python.exe -m timeit -s 'from fractions import Fraction; f = Fraction(3, 2)' 'Fraction(f)' 31.9 usec/loop -> 14.3 usec/loop
This commit is contained in:
parent
abe3237187
commit
1c214d6c94
|
@ -64,7 +64,7 @@ class Fraction(Rational):
|
|||
"""
|
||||
self = super(Fraction, cls).__new__(cls)
|
||||
|
||||
if denominator == 1:
|
||||
if type(numerator) not in (int, long) and denominator == 1:
|
||||
if isinstance(numerator, basestring):
|
||||
# Handle construction from strings.
|
||||
input = numerator
|
||||
|
@ -86,24 +86,22 @@ class Fraction(Rational):
|
|||
if m.group('sign') == '-':
|
||||
numerator = -numerator
|
||||
|
||||
elif (not isinstance(numerator, numbers.Integral) and
|
||||
isinstance(numerator, Rational)):
|
||||
# Handle copies from other rationals.
|
||||
elif isinstance(numerator, Rational):
|
||||
# Handle copies from other rationals. Integrals get
|
||||
# caught here too, but it doesn't matter because
|
||||
# denominator is already 1.
|
||||
other_rational = numerator
|
||||
numerator = other_rational.numerator
|
||||
denominator = other_rational.denominator
|
||||
|
||||
if (not isinstance(numerator, numbers.Integral) or
|
||||
not isinstance(denominator, numbers.Integral)):
|
||||
raise TypeError("Fraction(%(numerator)s, %(denominator)s):"
|
||||
" Both arguments must be integral." % locals())
|
||||
|
||||
if denominator == 0:
|
||||
raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
|
||||
|
||||
numerator = numerator.__index__()
|
||||
denominator = denominator.__index__()
|
||||
g = gcd(numerator, denominator)
|
||||
self._numerator = int(numerator // g)
|
||||
self._denominator = int(denominator // g)
|
||||
self._numerator = numerator // g
|
||||
self._denominator = denominator // g
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -62,11 +62,11 @@ class FractionTest(unittest.TestCase):
|
|||
|
||||
self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
|
||||
F, 12, 0)
|
||||
self.assertRaises(TypeError, F, 1.5)
|
||||
self.assertRaises(TypeError, F, 1.5 + 3j)
|
||||
self.assertRaises(AttributeError, F, 1.5)
|
||||
self.assertRaises(AttributeError, F, 1.5 + 3j)
|
||||
|
||||
self.assertRaises(TypeError, F, F(1, 2), 3)
|
||||
self.assertRaises(TypeError, F, "3/2", 3)
|
||||
self.assertRaises(AttributeError, F, F(1, 2), 3)
|
||||
self.assertRaises(AttributeError, F, "3/2", 3)
|
||||
|
||||
def testFromString(self):
|
||||
self.assertEquals((5, 1), _components(F("5")))
|
||||
|
|
Loading…
Reference in New Issue