Author: Armin Rigo <ar...@tunes.org> Branch: keys_with_hash Changeset: r79346:f45fa5542e6b Date: 2015-09-01 12:11 +0200 http://bitbucket.org/pypy/pypy/changeset/f45fa5542e6b/
Log: Use iteritems_with_hash() in dictmultiobject in order to let d1.update(d2) not recompute hashes diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py --- a/pypy/objspace/std/celldict.py +++ b/pypy/objspace/std/celldict.py @@ -3,7 +3,7 @@ indirection is introduced to make the version tag change less often. """ -from rpython.rlib import jit, rerased +from rpython.rlib import jit, rerased, objectmodel from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.dictmultiobject import ( @@ -162,8 +162,8 @@ def getitervalues(self, w_dict): return self.unerase(w_dict.dstorage).itervalues() - def getiteritems(self, w_dict): - return self.unerase(w_dict.dstorage).iteritems() + def getiteritems_with_hash(self, w_dict): + return objectmodel.iteritems_with_hash(self.unerase(w_dict.dstorage)) wrapkey = _wrapkey diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -511,7 +511,7 @@ def getitervalues(self, w_dict): raise NotImplementedError - def getiteritems(self, w_dict): + def getiteritems_with_hash(self, w_dict): raise NotImplementedError has_iterreversed = False @@ -634,7 +634,7 @@ def getitervalues(self, w_dict): return iter([]) - def getiteritems(self, w_dict): + def getiteritems_with_hash(self, w_dict): return iter([]) def getiterreversed(self, w_dict): @@ -751,11 +751,11 @@ class IterClassItems(BaseItemIterator): def __init__(self, space, strategy, impl): - self.iterator = strategy.getiteritems(impl) + self.iterator = strategy.getiteritems_with_hash(impl) BaseIteratorImplementation.__init__(self, space, strategy, impl) def next_item_entry(self): - for key, value in self.iterator: + for key, value, keyhash in self.iterator: return (wrapkey(self.space, key), wrapvalue(self.space, value)) else: @@ -793,10 +793,10 @@ # the logic is to call prepare_dict_update() after the first setitem(): # it gives the w_updatedict a chance to switch its strategy. if 1: # (preserve indentation) - iteritems = self.getiteritems(w_dict) + iteritemsh = self.getiteritems_with_hash(w_dict) if not same_strategy(self, w_updatedict): # Different strategy. Try to copy one item of w_dict - for key, value in iteritems: + for key, value, keyhash in iteritemsh: w_key = wrapkey(self.space, key) w_value = wrapvalue(self.space, value) w_updatedict.setitem(w_key, w_value) @@ -807,7 +807,7 @@ w_updatedict.strategy.prepare_update(w_updatedict, count) # If the strategy is still different, continue the slow way if not same_strategy(self, w_updatedict): - for key, value in iteritems: + for key, value, keyhash in iteritemsh: w_key = wrapkey(self.space, key) w_value = wrapvalue(self.space, value) w_updatedict.setitem(w_key, w_value) @@ -820,8 +820,8 @@ # wrapping/unwrapping the key. assert setitem_untyped is not None dstorage = w_updatedict.dstorage - for key, value in iteritems: - setitem_untyped(self, dstorage, key, value) + for key, value, keyhash in iteritemsh: + setitem_untyped(self, dstorage, key, value, keyhash) def same_strategy(self, w_otherdict): return (setitem_untyped is not None and @@ -945,8 +945,8 @@ def getitervalues(self, w_dict): return self.unerase(w_dict.dstorage).itervalues() - def getiteritems(self, w_dict): - return self.unerase(w_dict.dstorage).iteritems() + def getiteritems_with_hash(self, w_dict): + return objectmodel.iteritems_with_hash(self.unerase(w_dict.dstorage)) def getiterreversed(self, w_dict): return objectmodel.reversed_dict(self.unerase(w_dict.dstorage)) @@ -955,8 +955,9 @@ objectmodel.prepare_dict_update(self.unerase(w_dict.dstorage), num_extra) - def setitem_untyped(self, dstorage, key, w_value): - self.unerase(dstorage)[key] = w_value + def setitem_untyped(self, dstorage, key, w_value, keyhash): + d = self.unerase(dstorage) + objectmodel.setitem_with_hash(d, key, keyhash, w_value) class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy): diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py --- a/pypy/objspace/std/dictproxyobject.py +++ b/pypy/objspace/std/dictproxyobject.py @@ -1,4 +1,5 @@ from rpython.rlib import rerased +from rpython.rlib.objectmodel import iteritems_with_hash from pypy.interpreter.error import OperationError, oefmt from pypy.objspace.std.dictmultiobject import ( @@ -103,8 +104,8 @@ return self.unerase(w_dict.dstorage).dict_w.iterkeys() def getitervalues(self, w_dict): return self.unerase(w_dict.dstorage).dict_w.itervalues() - def getiteritems(self, w_dict): - return self.unerase(w_dict.dstorage).dict_w.iteritems() + def getiteritems_with_hash(self, w_dict): + return iteritems_with_hash(self.unerase(w_dict.dstorage).dict_w) def wrapkey(space, key): return space.wrap(key) def wrapvalue(space, value): diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py --- a/pypy/objspace/std/kwargsdict.py +++ b/pypy/objspace/std/kwargsdict.py @@ -3,7 +3,7 @@ Based on two lists containing unwrapped key value pairs. """ -from rpython.rlib import jit, rerased +from rpython.rlib import jit, rerased, objectmodel from pypy.objspace.std.dictmultiobject import ( BytesDictStrategy, DictStrategy, EmptyDictStrategy, ObjectDictStrategy, @@ -165,13 +165,14 @@ def getitervalues(self, w_dict): return iter(self.unerase(w_dict.dstorage)[1]) - def getiteritems(self, w_dict): - return Zip(*self.unerase(w_dict.dstorage)) + def getiteritems_with_hash(self, w_dict): + keys, values_w = self.unerase(w_dict.dstorage) + return ZipItemsWithHash(keys, values_w) wrapkey = _wrapkey -class Zip(object): +class ZipItemsWithHash(object): def __init__(self, list1, list2): assert len(list1) == len(list2) self.list1 = list1 @@ -186,6 +187,7 @@ if i >= len(self.list1): raise StopIteration self.i = i + 1 - return (self.list1[i], self.list2[i]) + key = self.list1[i] + return (key, self.list2[i], objectmodel.compute_hash(key)) create_iterator_classes(KwargsDictStrategy) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit