summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2020-03-10 17:47:21 -0500
committerJason Madden <jamadden@gmail.com>2020-03-18 12:26:35 -0500
commit01e0a7e36cecbd0a36fd49b08b1c21e0a5bba119 (patch)
tree978cb3c902c5c672ae5743827d0774e6e99a300c
parentb9165b790c831b6d8a87a3f27d4f135143494ff8 (diff)
downloadzope-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.py62
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,
{},