8000 bpo-37863: Optimize Fraction.__hash__() (#15298) · python/cpython@f3cb68f · GitHub
[go: up one dir, main page]

Skip to content

Commit f3cb68f

Browse files
authored
bpo-37863: Optimize Fraction.__hash__() (#15298)
1 parent 69f37bc commit f3cb68f

File tree

2 files changed

+12
-15
lines changed

2 files changed

+12
-15
lines changed

Lib/fractions.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -556,23 +556,19 @@ def __round__(self, ndigits=None):
556556
def __hash__(self):
557557
"""hash(self)"""
558558

559-
# XXX since this method is expensive, consider caching the result
560-
561-
# In order to make sure that the hash of a Fraction agrees
562-
# with the hash of a numerically equal integer, float or
563-
# Decimal instance, we follow the rules for numeric hashes
564-
# outlined in the documentation. (See library docs, 'Built-in
565-
# Types').
566-
567-
# dinv is the inverse of self._denominator modulo the prime
568-
# _PyHASH_MODULUS, or 0 if self._denominator is divisible by
569-
# _PyHASH_MODULUS.
570-
dinv = pow(self._denominator, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
571-
if not dinv:
559+
# To make sure that the hash of a Fraction agrees with the hash
560+
# of a numerically equal integer, float or Decimal instance, we
561+
# follow the rules for numeric hashes outlined in the
562+
# documentation. (See library docs, 'Built-in Types').
563+
564+
try:
565+
dinv = pow(self._denominator, -1, _PyHASH_MODULUS)
566+
except ValueError:
567+
# ValueError means there is no modular inverse
572568
hash_ = _PyHASH_INF
573569
else:
574-
hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS
575-
result = hash_ if self >= 0 else -hash_
570+
hash_ = hash(abs(self._numerator)) * dinv % _PyHASH_MODULUS
571+
result = hash_ if self._numerator >= 0 else -hash_
576572
return -2 if result == -1 else result
577573

578574
def __eq__(a, b):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Optimizations for Fraction.__hash__ suggested by Tim Peters.

0 commit comments

Comments
 (0)
0