Summary
py-multiaddr has no benchmark suite. Core hot-path operations — string parsing, byte (de)serialization, string formatting, protocol iteration, and encapsulation/decapsulation — have no performance baseline, so regressions in these paths can land silently and there's no data to guide optimization work.
Motivation
- Regression detection: These operations run on every multiaddr construction/comparison in downstream users (py-libp2p, etc.), often in tight loops (peer discovery, DHT routing tables, connection dialing). A silent slowdown in
Multiaddr.__init__ or to_bytes() would only surface as vague "things feel slower" reports from consumers.
- Informed optimization: Without a baseline, it's not possible to tell whether a proposed optimization (e.g. caching parsed components, avoiding repeated bytes conversions) actually helps.
- CI gating: A benchmark suite is a prerequisite for eventually wiring up
pytest-benchmark's comparison/fail-on-regression features in CI, so future PRs that touch parsing/serialization internals can be checked automatically rather than by manual review.
- Parity with intent of the library: Multiaddr is meant to be a lightweight, frequently-constructed value type; performance of construction and serialization is part of its core contract, not an afterthought.
Current Behavior
No benchmark tests exist. The only way to gauge performance today is manual, ad hoc timing during development.
Proposed Solution
Add a new dev dependency, pytest-benchmark, and a tests/test_benchmarks.py covering the core operations:
import pytest
from multiaddr import Multiaddr
BENCH_ADDR = "/ip4/1.2.3.4/tcp/80/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fkaDs"
@pytest.mark.benchmark
def test_bench_from_string(benchmark):
benchmark(Multiaddr, BENCH_ADDR)
@pytest.mark.benchmark
def test_bench_to_string(benchmark):
ma = Multiaddr(BENCH_ADDR)
benchmark(str, ma)
@pytest.mark.benchmark
def test_bench_to_bytes(benchmark):
ma = Multiaddr(BENCH_ADDR)
benchmark(ma.to_bytes)
@pytest.mark.benchmark
def test_bench_protocols(benchmark):
ma = Multiaddr(BENCH_ADDR)
benchmark(lambda: list(ma.protocols()))
@pytest.mark.benchmark
def test_bench_encapsulate(benchmark):
ma1 = Multiaddr("/ip4/1.2.3.4")
ma2 = Multiaddr("/tcp/80")
benchmark(ma1.encapsulate, ma2)
@pytest.mark.benchmark
def test_bench_decapsulate(benchmark):
ma = Multiaddr("/ip4/1.2.3.4/tcp/80")
benchmark(ma.decapsulate, "/tcp/80")
Covers, at minimum:
- Parsing: string →
Multiaddr (from_string path)
- Formatting:
Multiaddr → string (__str__)
- Serialization:
Multiaddr → bytes (to_bytes)
- Iteration: enumerating protocol components
- Composition:
encapsulate / decapsulate
References
Summary
py-multiaddrhas no benchmark suite. Core hot-path operations — string parsing, byte (de)serialization, string formatting, protocol iteration, and encapsulation/decapsulation — have no performance baseline, so regressions in these paths can land silently and there's no data to guide optimization work.Motivation
Multiaddr.__init__orto_bytes()would only surface as vague "things feel slower" reports from consumers.pytest-benchmark's comparison/fail-on-regression features in CI, so future PRs that touch parsing/serialization internals can be checked automatically rather than by manual review.Current Behavior
No benchmark tests exist. The only way to gauge performance today is manual, ad hoc timing during development.
Proposed Solution
Add a new dev dependency,
pytest-benchmark, and atests/test_benchmarks.pycovering the core operations:Covers, at minimum:
Multiaddr(from_stringpath)Multiaddr→ string (__str__)Multiaddr→ bytes (to_bytes)encapsulate/decapsulateReferences
pytest-benchmarkdocumentation