[pypy-commit] pypy kwargsdict-strategy: limit size of the kwargsdict to (for now) 16

cfbolz noreply at buildbot.pypy.org
Sat Apr 7 15:04:19 CEST 2012


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: kwargsdict-strategy
Changeset: r54228:dfac680a26f9
Date: 2012-04-06 10:43 +0200
http://bitbucket.org/pypy/pypy/changeset/dfac680a26f9/

Log:	limit size of the kwargsdict to (for now) 16

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
@@ -4,7 +4,8 @@
 from pypy.rlib import rerased, jit
 from pypy.objspace.std.dictmultiobject import (DictStrategy,
                                                IteratorImplementation,
-                                               ObjectDictStrategy)
+                                               ObjectDictStrategy,
+                                               StringDictStrategy)
 
 
 class KwargsDictStrategy(DictStrategy):
@@ -54,8 +55,13 @@
                 values_w[i] = w_value
                 break
         else:
-            keys.append(key)
-            values_w.append(w_value)
+            # limit the size so that the linear searches don't become too long
+            if len(keys) >= 16:
+                self.switch_to_string_strategy(w_dict)
+                w_dict.setitem_str(key, w_value)
+            else:
+                keys.append(key)
+                values_w.append(w_value)
 
     def setdefault(self, w_dict, w_key, w_default):
         # XXX could do better, but is it worth it?
@@ -122,6 +128,17 @@
         w_dict.strategy = strategy
         w_dict.dstorage = strategy.erase(d_new)
 
+    def switch_to_string_strategy(self, w_dict):
+        strategy = self.space.fromcache(StringDictStrategy)
+        keys, values_w = self.unerase(w_dict.dstorage)
+        storage = strategy.get_empty_storage()
+        d_new = strategy.unerase(storage)
+        for i in range(len(keys)):
+            d_new[keys[i]] = values_w[i]
+        w_dict.strategy = strategy
+        w_dict.dstorage = storage
+
+
 class KwargsDictIterator(IteratorImplementation):
     def __init__(self, space, strategy, dictimplementation):
         IteratorImplementation.__init__(self, space, strategy, dictimplementation)
diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py
--- a/pypy/objspace/std/test/test_kwargsdict.py
+++ b/pypy/objspace/std/test/test_kwargsdict.py
@@ -67,6 +67,13 @@
     assert keys == ["a", "b", "c", "d"]
     assert values == [1, 2, 3, 4]
 
+def test_limit_size():
+    storage = strategy.get_empty_storage()
+    d = W_DictMultiObject(space, strategy, storage)
+    for i in range(100):
+        assert d.setitem_str("d%s" % i, 4) is None
+    assert d.strategy is not strategy
+    assert "StringDictStrategy" == d.strategy.__class__.__name__
 
 from pypy.objspace.std.test.test_dictmultiobject import BaseTestRDictImplementation, BaseTestDevolvedDictImplementation
 def get_impl(self):


More information about the pypy-commit mailing list