[pypy-commit] pypy set-strategies: (cfbolz, l.diekmann): added fastpath for dict.keys if keys are strings
l.diekmann
noreply at buildbot.pypy.org
Wed Jan 11 15:55:32 CET 2012
Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: set-strategies
Changeset: r51230:a26b3141a0d4
Date: 2012-01-11 15:55 +0100
http://bitbucket.org/pypy/pypy/changeset/a26b3141a0d4/
Log: (cfbolz, l.diekmann): added fastpath for dict.keys if keys are
strings
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
@@ -127,10 +127,10 @@
def iter(self, w_dict):
return ModuleDictIteratorImplementation(self.space, self, w_dict)
- def keys(self, w_dict):
+ def w_keys(self, w_dict):
space = self.space
- iterator = self.unerase(w_dict.dstorage).iteritems
- return [space.wrap(key) for key, cell in iterator()]
+ l = self.unerase(w_dict.dstorage).keys()
+ return space.newlist_str(l)
def values(self, w_dict):
iterator = self.unerase(w_dict.dstorage).itervalues
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
@@ -89,7 +89,7 @@
def _add_indirections():
dict_methods = "setitem setitem_str getitem \
getitem_str delitem length \
- clear keys values \
+ clear w_keys values \
items iter setdefault \
popitem listview_str listview_int".split()
@@ -112,7 +112,7 @@
def get_empty_storage(self):
raise NotImplementedError
- def keys(self, w_dict):
+ def w_keys(self, w_dict):
iterator = self.iter(w_dict)
result = []
while 1:
@@ -120,7 +120,7 @@
if w_key is not None:
result.append(w_key)
else:
- return result
+ return self.space.newlist(result)
def values(self, w_dict):
iterator = self.iter(w_dict)
@@ -364,8 +364,9 @@
self.switch_to_object_strategy(w_dict)
return w_dict.getitem(w_key)
- def keys(self, w_dict):
- return [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+ def w_keys(self, w_dict):
+ l = [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+ return self.space.newlist(l)
def values(self, w_dict):
return self.unerase(w_dict.dstorage).values()
@@ -418,8 +419,8 @@
def iter(self, w_dict):
return ObjectIteratorImplementation(self.space, self, w_dict)
- def keys(self, w_dict):
- return self.unerase(w_dict.dstorage).keys()
+ def w_keys(self, w_dict):
+ return self.space.newlist(self.unerase(w_dict.dstorage).keys())
class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
@@ -468,6 +469,9 @@
def iter(self, w_dict):
return StrIteratorImplementation(self.space, self, w_dict)
+ def w_keys(self, w_dict):
+ return self.space.newlist_str(self.listview_str(w_dict))
+
class _WrappedIteratorMixin(object):
_mixin_ = True
@@ -533,6 +537,11 @@
def listview_int(self, w_dict):
return self.unerase(w_dict.dstorage).keys()
+ def w_keys(self, w_dict):
+ # XXX there is no space.newlist_int yet
+ space = self.space
+ return space.call_function(space.w_list, w_dict)
+
class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
pass
@@ -687,8 +696,7 @@
return space.newlist(w_self.items())
def dict_keys__DictMulti(space, w_self):
- #XXX add fastpath for strategies here
- return space.newlist(w_self.keys())
+ return w_self.w_keys()
def dict_values__DictMulti(space, w_self):
return space.newlist(w_self.values())
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
@@ -75,7 +75,7 @@
def keys(self, w_dict):
space = self.space
- return [space.wrap(key) for key in self.unerase(w_dict.dstorage).dict_w.iterkeys()]
+ return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys())
def values(self, w_dict):
return [unwrap_cell(self.space, w_value) for w_value in self.unerase(w_dict.dstorage).dict_w.itervalues()]
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -694,6 +694,8 @@
self.delitem(w_dict, w_key)
return (w_key, w_value)
+ # XXX could implement a more efficient w_keys based on space.newlist_str
+
def materialize_r_dict(space, obj, dict_w):
map = obj._get_mapdict_map()
new_obj = map.materialize_r_dict(space, obj, dict_w)
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -157,6 +157,20 @@
assert self.space.listview_int(w_d) == [1, 2]
+ def test_keys_on_string_int_dict(self):
+ w = self.space.wrap
+ w_d = self.space.newdict()
+ w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))])
+
+ w_l = self.space.call_method(w_d, "keys")
+ assert sorted(self.space.listview_int(w_l)) == [1,2]
+
+ w_d = self.space.newdict()
+ w_d.initialize_content([(w("a"), w(1)), (w("b"), w(6))])
+
+ w_l = self.space.call_method(w_d, "keys")
+ assert sorted(self.space.listview_str(w_l)) == ["a", "b"]
+
class AppTest_DictObject:
def setup_class(cls):
cls.w_on_pypy = cls.space.wrap("__pypy__" in sys.builtin_module_names)
@@ -816,7 +830,9 @@
return x == y
eq_w = eq
def newlist(self, l):
- return []
+ return l
+ def newlist_str(self, l):
+ return l
DictObjectCls = W_DictMultiObject
def type(self, w_obj):
if isinstance(w_obj, FakeString):
@@ -956,7 +972,7 @@
def test_keys(self):
self.fill_impl()
- keys = self.impl.keys()
+ keys = self.impl.w_keys() # wrapped lists = lists in the fake space
keys.sort()
assert keys == [self.string, self.string2]
self.check_not_devolved()
@@ -1034,8 +1050,8 @@
d.setitem("s", 12)
d.delitem(F())
- assert "s" not in d.keys()
- assert F() not in d.keys()
+ assert "s" not in d.w_keys()
+ assert F() not in d.w_keys()
class TestStrDictImplementation(BaseTestRDictImplementation):
StrategyClass = StringDictStrategy
More information about the pypy-commit
mailing list