Skip to content

Commit

Permalink
performance: store cached hashvalue in slot (~1.6x faster)
Browse files Browse the repository at this point in the history
  • Loading branch information
jensens committed Feb 16, 2020
1 parent 7f6f60e commit ea4457f
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/zope/interface/_zope_interface_coptimizations.c
Expand Up @@ -277,6 +277,7 @@ typedef struct {
PyObject* _v_attrs;
PyObject* __iro__;
PyObject* __sro__;
PyObject* _hashvalue;
} Spec;

/*
Expand All @@ -291,6 +292,7 @@ Spec_traverse(Spec* self, visitproc visit, void* arg)
Py_VISIT(self->_v_attrs);
Py_VISIT(self->__iro__);
Py_VISIT(self->__sro__);
Py_VISIT(self->_hashvalue);
return 0;
}

Expand All @@ -302,6 +304,7 @@ Spec_clear(Spec* self)
Py_CLEAR(self->_v_attrs);
Py_CLEAR(self->__iro__);
Py_CLEAR(self->__sro__);
Py_CLEAR(self->_hashvalue);
return 0;
}

Expand Down Expand Up @@ -413,6 +416,7 @@ static PyMemberDef Spec_members[] = {
{"_v_attrs", T_OBJECT_EX, offsetof(Spec, _v_attrs), 0, ""},
{"__iro__", T_OBJECT_EX, offsetof(Spec, __iro__), 0, ""},
{"__sro__", T_OBJECT_EX, offsetof(Spec, __sro__), 0, ""},
{"_hashvalue", T_OBJECT_EX, offsetof(Spec, _hashvalue), 0, ""},
{NULL},
};

Expand Down
2 changes: 2 additions & 0 deletions src/zope/interface/declarations.py
Expand Up @@ -180,6 +180,8 @@ def weakref(self, callback=None):
# object, and that includes a method.)
return _ImmutableDeclaration

_hashvalue = hash((__module__, '_empty'))


##############################################################################
#
Expand Down
9 changes: 5 additions & 4 deletions src/zope/interface/interface.py
Expand Up @@ -131,6 +131,8 @@ class SpecificationBase(object):
'__iro__',
'__sro__',
'__weakref__',
# Things used in InterfaceClass.
'_hashvalue',
)

def providedBy(self, ob):
Expand Down Expand Up @@ -598,10 +600,10 @@ def __cmp(self, other):

def __hash__(self):
try:
return self._v_cached_hash
return self._hashvalue
except AttributeError:
self._v_cached_hash = hash((self.__name__, self.__module__))
return self._v_cached_hash
self._hashvalue = hash((self.__name__, self.__module__))
return self._hashvalue

def __eq__(self, other):
c = self.__cmp(other)
Expand All @@ -627,7 +629,6 @@ def __ge__(self, other):
c = self.__cmp(other)
return c >= 0


Interface = InterfaceClass("Interface", __module__='zope.interface')


Expand Down

0 comments on commit ea4457f

Please sign in to comment.