diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-22 00:06:06 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-23 00:05:13 -0400 |
commit | fcbd03e48af50e301e0dcbade75765a4d3e4999f (patch) | |
tree | 8a30c4b9811bb217430c6bafea040753729c80ae /test/base/test_utils.py | |
parent | d45657a2f5b880dc22dda2d1eb1687af5234a470 (diff) | |
download | sqlalchemy-fcbd03e48af50e301e0dcbade75765a4d3e4999f.tar.gz |
Add immutabledict C code
Start trying to convert fundamental objects to
C as we now rely on a fairly small core of things,
and 1.4 is having problems with complexity added being
slower than the performance gains we are trying to build in.
immutabledict here does seem to bench as twice as fast as the
Python one, see below. However, it does not appear to be
used prominently enough to make any dent in the performance
tests.
at the very least it may provide us some more lift-and-copy
code for more C extensions.
import timeit
from sqlalchemy.util._collections import not_immutabledict, immutabledict
def run(dict_cls):
for i in range(1000000):
d1 = dict_cls({"x": 5, "y": 4})
d2 = d1.union({"x": 17, "new key": "some other value"}, None)
assert list(d2) == ["x", "y", "new key"]
print(
timeit.timeit(
"run(d)", "from __main__ import run, not_immutabledict as d", number=1
)
)
print(
timeit.timeit(
"run(d)", "from __main__ import run, immutabledict as d", number=1
)
)
output:
python: 1.8799766399897635
C code: 0.8880784640205093
Change-Id: I29e7104dc21dcc7cdf895bf274003af2e219bf6d
Diffstat (limited to 'test/base/test_utils.py')
-rw-r--r-- | test/base/test_utils.py | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/test/base/test_utils.py b/test/base/test_utils.py index a6d777c61..bba0cc16c 100644 --- a/test/base/test_utils.py +++ b/test/base/test_utils.py @@ -141,11 +141,100 @@ class OrderedSetTest(fixtures.TestBase): eq_(o.union(iter([3, 4, 6])), util.OrderedSet([2, 3, 4, 5, 6])) -class FrozenDictTest(fixtures.TestBase): +class ImmutableDictTest(fixtures.TestBase): + def test_union_no_change(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.union({}) + + is_(d2, d) + + def test_merge_with_no_change(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.merge_with({}, None) + + eq_(d2, {1: 2, 3: 4}) + is_(d2, d) + + def test_merge_with_dicts(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.merge_with({3: 5, 7: 12}, {9: 18, 15: 25}) + + eq_(d, {1: 2, 3: 4}) + eq_(d2, {1: 2, 3: 5, 7: 12, 9: 18, 15: 25}) + assert isinstance(d2, util.immutabledict) + + d3 = d.merge_with({17: 42}) + + eq_(d3, {1: 2, 3: 4, 17: 42}) + + def test_merge_with_tuples(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.merge_with([(3, 5), (7, 12)], [(9, 18), (15, 25)]) + + eq_(d, {1: 2, 3: 4}) + eq_(d2, {1: 2, 3: 5, 7: 12, 9: 18, 15: 25}) + + def test_union_dictionary(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.union({3: 5, 7: 12}) + assert isinstance(d2, util.immutabledict) + + eq_(d, {1: 2, 3: 4}) + eq_(d2, {1: 2, 3: 5, 7: 12}) + + def test_union_tuples(self): + d = util.immutabledict({1: 2, 3: 4}) + + d2 = d.union([(3, 5), (7, 12)]) + + eq_(d, {1: 2, 3: 4}) + eq_(d2, {1: 2, 3: 5, 7: 12}) + + def test_keys(self): + d = util.immutabledict({1: 2, 3: 4}) + + eq_(set(d.keys()), {1, 3}) + + def test_values(self): + d = util.immutabledict({1: 2, 3: 4}) + + eq_(set(d.values()), {2, 4}) + + def test_items(self): + d = util.immutabledict({1: 2, 3: 4}) + + eq_(set(d.items()), {(1, 2), (3, 4)}) + + def test_contains(self): + d = util.immutabledict({1: 2, 3: 4}) + + assert 1 in d + assert "foo" not in d + + def test_rich_compare(self): + d = util.immutabledict({1: 2, 3: 4}) + d2 = util.immutabledict({1: 2, 3: 4}) + d3 = util.immutabledict({5: 12}) + d4 = {5: 12} + + eq_(d, d2) + ne_(d, d3) + ne_(d, d4) + eq_(d3, d4) + def test_serialize(self): d = util.immutabledict({1: 2, 3: 4}) for loads, dumps in picklers(): - print(loads(dumps(d))) + d2 = loads(dumps(d)) + + eq_(d2, {1: 2, 3: 4}) + + assert isinstance(d2, util.immutabledict) class MemoizedAttrTest(fixtures.TestBase): |