Skip to content

Replace hash_gid std::stringstream with FNV-1a - #1028

Draft
zacheryasc wants to merge 1 commit into
ros2:rollingfrom
zacheryasc:perf/hash-gid-fnv1a
Draft

Replace hash_gid std::stringstream with FNV-1a#1028
zacheryasc wants to merge 1 commit into
ros2:rollingfrom
zacheryasc:perf/hash-gid-fnv1a

Conversation

@zacheryasc

Copy link
Copy Markdown

Description

hash_gid hashes a 16-byte GID (RMW_GID_STORAGE_SIZE) into a size_t map
key. It runs on rmw_zenoh's hot paths:

  • SubscriptionData::add_new_message — every message received
  • ServiceData::take_request / send_response — every request / response

The current implementation builds a std::stringstream (with std::hex) on
every call, heap-allocating a stream buffer and a std::string per
invocation. This replaces it with FNV-1a over the raw GID bytes, which is
allocation-free.

The returned value is used only as an in-memory map key (Entity::gid_hash_
and the gid_hash()-keyed event/discovery maps); it is never serialized into
attachments, key expressions, or config. The algorithm is therefore not part
of any wire or persisted format, so swapping it is externally invisible.

Related

Narrower alternative to #422 ("Replace hash_gid with FNV-1a"), which has
been open but not marked ready-for-review since Jan 2025. #422 additionally
rekeys the two message-path maps from size_t to a Gid alias and
specializes std::hash<std::array<uint8_t, RMW_GID_STORAGE_SIZE>>. This change
keeps the maps keyed on size_t (minimal blast radius) and avoids that
specialization, which is formally disallowed by [namespace.std] — a standard
template may only be specialized when it depends on a program-defined type, and
std::array<uint8_t, N> does not.

Performance

Per-call heap allocations on the message/request hot paths are eliminated
(2 -> 0, deterministic and machine-independent).

How was it tested

  • Builds clean on Rolling against the released Zenoh vendor
    (ros-rolling-zenoh-cpp-vendor).
  • colcon test --packages-select test_rmw_zenoh_cpp: 15/15 pass, including
    cpplint and uncrustify.
  • End-to-end over the patched rmw_zenoh: a ros2 talker/listener (message
    received) and an add_two_ints service call (sum=42), exercising both
    changed call sites through hash_gid.

Checklist

  • DCO sign-off
  • Code style (cpplint + uncrustify pass)
  • Self-reviewed

hash_gid runs on the per-message (SubscriptionData::add_new_message) and per-request (ServiceData::take_request/send_response) hot paths and allocated a std::stringstream on every call. Replace with FNV-1a over the raw GID bytes, which is allocation-free. The return value is used only as an in-memory map key, so the algorithm is not part of any wire or persisted format.

Signed-off-by: Zachery Aaron Shores-Chmielewski <zacheryasc@gmail.com>
@mergify

mergify Bot commented Aug 4, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@Yadunund

Copy link
Copy Markdown
Member

@zacheryasc thanks for the PR.
iirc as part of #422, we arrived at the conclusion that FNV-1a may not always be more performant. See https://github.com/ros2/rmw_zenoh/pull/422/changes#r1927532643. Let's try to close the loop there first.

Lastly kindly update the PR description to follow our template and specifically acknowledge AI usage if any.

@zacheryasc

Copy link
Copy Markdown
Author

@zacheryasc thanks for the PR. iirc as part of #422, we arrived at the conclusion that FNV-1a may not always be more performant. See https://github.com/ros2/rmw_zenoh/pull/422/changes#r1927532643. Let's try to close the loop there first.

I will set this to a draft, to be revisited if and or when a decision is found.

Lastly kindly update the PR description to follow our template and specifically acknowledge AI usage if any.

I filled the template that was given when I opened the PR. Is there a better template? Where? AI was used for git archaeology, however code changes are my own.

@zacheryasc
zacheryasc marked this pull request as draft August 20, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants