[pypy-commit] pypy rdict-fast-hash: a branch to support fast hash functions with r_dict
cfbolz
pypy.commits at gmail.com
Mon Dec 11 11:40:47 EST 2017
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: rdict-fast-hash
Changeset: r93364:bd78548cee25
Date: 2017-12-11 15:50 +0100
http://bitbucket.org/pypy/pypy/changeset/bd78548cee25/
Log: a branch to support fast hash functions with r_dict
get as fast as the first test failing
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -237,12 +237,17 @@
return SomeInstance(clsdef)
@analyzer_for(rpython.rlib.objectmodel.r_dict)
-def robjmodel_r_dict(s_eqfn, s_hashfn, s_force_non_null=None):
+def robjmodel_r_dict(s_eqfn, s_hashfn, s_force_non_null=None, s_fast_hash=None):
if s_force_non_null is None:
force_non_null = False
else:
assert s_force_non_null.is_constant()
force_non_null = s_force_non_null.const
+ if s_fast_hash is None:
+ fast_hash = False
+ else:
+ assert s_fast_hash.is_constant()
+ fast_hash = s_fast_hash.const
dictdef = getbookkeeper().getdictdef(is_r_dict=True,
force_non_null=force_non_null)
dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -748,11 +748,12 @@
def _newdict(self):
return {}
- def __init__(self, key_eq, key_hash, force_non_null=False):
+ def __init__(self, key_eq, key_hash, force_non_null=False, fast_hash=False):
self._dict = self._newdict()
self.key_eq = key_eq
self.key_hash = key_hash
self.force_non_null = force_non_null
+ self.fast_hash = fast_hash
def __getitem__(self, key):
return self._dict[_r_dictkey(self, key)]
diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -330,6 +330,13 @@
res = self.interpret(g, [3])
assert res == 77
+ def test_r_dict_fast_functions(self):
+ def fn():
+ d1 = r_dict(strange_key_eq, strange_key_hash, fast_hash=True)
+ return play_with_r_dict(d1)
+ res = self.interpret(fn, [])
+ assert res
+
def test_prepare_dict_update(self):
def g(n):
d = {}
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -717,9 +717,9 @@
@typer_for(OrderedDict)
@typer_for(objectmodel.r_dict)
@typer_for(objectmodel.r_ordereddict)
-def rtype_dict_constructor(hop, i_force_non_null=None):
- # 'i_force_non_null' is ignored here; if it has any effect, it
- # has already been applied to 'hop.r_result'
+def rtype_dict_constructor(hop, i_force_non_null=None, i_fast_hash=None):
+ # 'i_force_non_null' and 'i_fast_hash' are ignored here; if they have any
+ # effect, it has already been applied to 'hop.r_result'
hop.exception_cannot_occur()
r_dict = hop.r_result
cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
diff --git a/rpython/rtyper/test/test_rdict.py b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -538,6 +538,25 @@
r_dict = rtyper.getrepr(s)
assert not hasattr(r_dict.lowleveltype.TO.entries.TO.OF, "f_hash")
+ def test_r_dict_can_be_fast(self):
+ def myeq(n, m):
+ return n == m
+ def myhash(n):
+ return ~n
+ def f():
+ d = self.new_r_dict(myeq, myhash, fast_hash=True)
+ d[5] = 7
+ d[12] = 19
+ return d
+
+ t = TranslationContext()
+ s = t.buildannotator().build_types(f, [])
+ rtyper = t.buildrtyper()
+ rtyper.specialize()
+
+ r_dict = rtyper.getrepr(s)
+ assert not hasattr(r_dict.lowleveltype.TO.entries.TO.OF, "f_hash")
+
def test_tuple_dict(self):
def f(i):
d = self.newdict()
@@ -1000,8 +1019,8 @@
return {}
@staticmethod
- def new_r_dict(myeq, myhash):
- return r_dict(myeq, myhash)
+ def new_r_dict(myeq, myhash, force_non_null=False, fast_hash=False):
+ return r_dict(myeq, myhash, force_non_null=force_non_null, fast_hash=fast_hash)
def test_two_dicts_with_different_value_types(self):
def func(i):
More information about the pypy-commit
mailing list