Skip to content

Commit

Permalink
Benchmarks looking up adapters from components.
Browse files Browse the repository at this point in the history
Current results (this branch vs master, 354facc):

| 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.
  • Loading branch information
jamadden committed Mar 17, 2020
1 parent b745957 commit abc51b1
Showing 1 changed file with 60 additions and 2 deletions.
62 changes: 60 additions & 2 deletions 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()
Expand All @@ -18,8 +37,47 @@ 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,
Expand Down

0 comments on commit abc51b1

Please sign in to comment.