Serhiy Storchaka <storch...@gmail.com> added the comment:
> The patch for the Python version looks good to me
Oh, but used by James Hutchison approach is faster. When I disable the
_decimal:
Unpatched:
int: 2.24056077003479
CachingDecimal: 8.49468207359314
Decimal: 187.68132972717285
With rhettinger's LBYL patch:
int: 2.1670639514923096
CachingDecimal: 8.790924310684204
Decimal: 10.426796436309814
With EAFP patch:
int: 2.1392786502838135
CachingDecimal: 8.431122303009033
Decimal: 8.263015270233154
----------
Added file: http://bugs.python.org/file25169/decimal_hash_2.patch
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue14478>
_______________________________________
diff -r a012d5df2c73 Lib/decimal.py
--- a/Lib/decimal.py Tue Apr 10 16:27:58 2012 +0200
+++ b/Lib/decimal.py Tue Apr 10 18:46:19 2012 +0300
@@ -547,7 +547,7 @@
class Decimal(object):
"""Floating point class for decimal arithmetic."""
- __slots__ = ('_exp','_int','_sign', '_is_special')
+ __slots__ = ('_exp','_int','_sign', '_is_special', '_hash')
# Generally, the value of the Decimal instance is given by
# (-1)**_sign * _int * 10**_exp
# Special values are signified by _is_special == True
@@ -983,6 +983,10 @@
def __hash__(self):
"""x.__hash__() <==> hash(x)"""
+ try:
+ return self._hash
+ except AttributeError:
+ pass
# In order to make sure that the hash of a Decimal instance
# agrees with the hash of a numerically equal integer, float
@@ -992,20 +996,22 @@
if self.is_snan():
raise TypeError('Cannot hash a signaling NaN value.')
elif self.is_nan():
- return _PyHASH_NAN
+ hash_ = _PyHASH_NAN
else:
if self._sign:
- return -_PyHASH_INF
+ hash_ = -_PyHASH_INF
else:
- return _PyHASH_INF
-
- if self._exp >= 0:
- exp_hash = pow(10, self._exp, _PyHASH_MODULUS)
+ hash_ = _PyHASH_INF
else:
- exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS)
- hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS
- ans = hash_ if self >= 0 else -hash_
- return -2 if ans == -1 else ans
+ if self._exp >= 0:
+ exp_hash = pow(10, self._exp, _PyHASH_MODULUS)
+ else:
+ exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS)
+ hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS
+ if self < 0: hash_ = -hash_
+ if hash_ == -1: hash_ = -2
+ self._hash = hash_
+ return hash_
def as_tuple(self):
"""Represents the number as a triple tuple.
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com