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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions