diff options
author | Jason Madden <jamadden@gmail.com> | 2020-03-10 17:47:21 -0500 |
---|---|---|
committer | Jason Madden <jamadden@gmail.com> | 2020-03-18 12:26:35 -0500 |
commit | 01e0a7e36cecbd0a36fd49b08b1c21e0a5bba119 (patch) | |
tree | 978cb3c902c5c672ae5743827d0774e6e99a300c | |
parent | b9165b790c831b6d8a87a3f27d4f135143494ff8 (diff) | |
download | zope-interface-01e0a7e36cecbd0a36fd49b08b1c21e0a5bba119.tar.gz |
Benchmarks looking up adapters from components.
Current results (this branch vs master, 354faccebd5b612a2ac8e081a7e5d2f7fb1089c1):
| Benchmark | 38-master | 38-faster |
|-------------------------------------------|-----------|-------------------------------|
| query adapter (no registrations) | 3.81 ms | 3.03 ms: 1.26x faster (-20%) |
| query adapter (all trivial registrations) | 4.65 ms | 3.90 ms: 1.19x faster (-16%) |
| contains (empty dict) | 163 ns | 76.1 ns: 2.14x faster (-53%) |
| contains (populated dict) | 162 ns | 76.9 ns: 2.11x faster (-53%) |
| contains (populated list) | 40.3 us | 3.09 us: 13.04x faster (-92%) |
Also need benchmarks using inheritance. The 'implied' data structures
are also hash/equality based.
-rw-r--r-- | benchmarks/micro.py | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/benchmarks/micro.py b/benchmarks/micro.py index 0494b56..9031261 100644 --- a/benchmarks/micro.py +++ b/benchmarks/micro.py @@ -1,14 +1,33 @@ import pyperf from zope.interface import Interface +from zope.interface import classImplements from zope.interface.interface import InterfaceClass +from zope.interface.registry import Components +# Long, mostly similar names are a worst case for equality +# comparisons. ifaces = [ - InterfaceClass('I' + str(i), (Interface,), {}) + InterfaceClass('I' + ('0' * 20) + str(i), (Interface,), {}) for i in range(100) ] -INNER = 1000 +def make_implementer(iface): + c = type('Implementer' + iface.__name__, (object,), {}) + classImplements(c, iface) + return c + +implementers = [ + make_implementer(iface) + for iface in ifaces +] + +providers = [ + implementer() + for implementer in implementers +] + +INNER = 10 def bench_in(loops, o): t0 = pyperf.perf_counter() @@ -18,9 +37,48 @@ def bench_in(loops, o): return pyperf.perf_counter() - t0 +def bench_query_adapter(loops, components): + # One time through to prime the caches + for iface in ifaces: + for provider in providers: + components.queryAdapter(provider, iface) + + t0 = pyperf.perf_counter() + for _ in range(loops): + for iface in ifaces: + for provider in providers: + components.queryAdapter(provider, iface) + return pyperf.perf_counter() - t0 + runner = pyperf.Runner() runner.bench_time_func( + 'query adapter (no registrations)', + bench_query_adapter, + Components(), + inner_loops=1 +) + +def populate_components(): + + def factory(o): + return 42 + + pop_components = Components() + for iface in ifaces: + for other_iface in ifaces: + pop_components.registerAdapter(factory, (iface,), other_iface, event=False) + + return pop_components + +runner.bench_time_func( + 'query adapter (all trivial registrations)', + bench_query_adapter, + populate_components(), + inner_loops=1 +) + +runner.bench_time_func( 'contains (empty dict)', bench_in, {}, |