Skip to content

Protocol.size and Protocol.path properties call codec_by_name() on every access #113

Description

@sumanjeet0012

Protocol.size and Protocol.path properties call codec_by_name() on every access, which does a dict lookup (and on first access, a module import via importlib). These should be cached since the codec for a protocol never changes.

Problem

In multiaddr/protocols.py:

class Protocol:
    @property
    def size(self) -> int:
        return codec_by_name(self.codec).SIZE    # ← Called every time

    @property
    def path(self) -> bool:
        return codec_by_name(self.codec).IS_PATH  # ← Called every time

codec_by_name() does:

def codec_by_name(name):
    if name is None:
        return NoneCodec()
    codec = CODEC_CACHE.get(name)
    if codec is None:
        module = importlib.import_module(f".{name}", __name__)  # ← Module import!
        codec_class = getattr(module, "Codec")
        codec = codec_class()
        CODEC_CACHE[name] = codec
    return codec

The first access triggers a module import. Subsequent accesses do a dict lookup + attribute access. For hot paths that access size or path repeatedly (e.g., bytes_iter(), string_iter()), this adds unnecessary overhead.

Proposed Solution

Cache the codec on the Protocol instance:

class Protocol:
    __slots__ = ["code", "codec", "name", "_codec_obj"]

    def __init__(self, code, name, codec):
        self.code = code
        self.name = name
        self.codec = codec
        self._codec_obj = None

    @property
    def size(self) -> int:
        if self._codec_obj is None:
            self._codec_obj = codec_by_name(self.codec)
        return self._codec_obj.SIZE

    @property
    def path(self) -> bool:
        if self._codec_obj is None:
            self._codec_obj = codec_by_name(self.codec)
        return self._codec_obj.IS_PATH

Related

  • File: multiaddr/protocols.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions