mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
bpo-35588: Speed up mod, divmod and floordiv operations for Fraction type (#11322)
* bpo-35588: Implement mod and divmod operations for Fraction type by spelling out the numerator/denominator calculation, instead of instantiating and normalising Fractions along the way. This speeds up '%' and divmod() by 2-3x. * bpo-35588: Also reimplement Fraction.__floordiv__() using integer operations to make it ~4x faster. * Improve code formatting. Co-Authored-By: scoder <stefan_ml@behnel.de> * bpo-35588: Fix return type of divmod(): the result of the integer division should be an integer. * bpo-35588: Further specialise __mod__() and inline the original helper function _flat_divmod() since it's no longer reused. * bpo-35588: Add some tests with large numerators and/or denominators. * bpo-35588: Use builtin "divmod()" function for implementing __divmod__() in order to simplify the implementation, even though performance results are mixed. * Rremove accidentally added empty line. * bpo-35588: Try to provide more informative output on test failures. * bpo-35588: Improve wording in News entry. Co-Authored-By: scoder <stefan_ml@behnel.de> * Remove stray space.
This commit is contained in:
parent
a1d1425306
commit
3a374e0c5a
3 changed files with 63 additions and 4 deletions
|
@ -429,14 +429,22 @@ class Fraction(numbers.Rational):
|
|||
|
||||
def _floordiv(a, b):
|
||||
"""a // b"""
|
||||
return math.floor(a / b)
|
||||
return (a.numerator * b.denominator) // (a.denominator * b.numerator)
|
||||
|
||||
__floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
|
||||
|
||||
def _divmod(a, b):
|
||||
"""(a // b, a % b)"""
|
||||
da, db = a.denominator, b.denominator
|
||||
div, n_mod = divmod(a.numerator * db, da * b.numerator)
|
||||
return div, Fraction(n_mod, da * db)
|
||||
|
||||
__divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
|
||||
|
||||
def _mod(a, b):
|
||||
"""a % b"""
|
||||
div = a // b
|
||||
return a - b * div
|
||||
da, db = a.denominator, b.denominator
|
||||
return Fraction((a.numerator * db) % (b.numerator * da), da * db)
|
||||
|
||||
__mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue