HORUS Benchmarks

Performance validation with real-world robotics workloads.

Benchmark Methodology

Measurement Approach

  • Statistical sampling: Criterion.rs micro-benchmarks, sample sizes 10-1000 depending on the group
  • Confidence intervals: Bootstrap 95% CI with Tukey IQR outlier detection
  • Controlled methodology: 2-10s measurement windows per group, Criterion's default 3s warm-up
  • Standalone binaries: 20,000-1,000,000 samples per scenario depending on the binary; all_paths_latency, robotics_messages_benchmark, determinism_benchmark and cross_process_benchmark are RDTSC-timed with calibrated overhead subtraction, topic_probe uses CLOCK_MONOTONIC (producer and consumer are threads in one process, so it is offset-free by construction)
  • Comprehensive coverage: 4 robotics message types, 10 backend routes

Workload Testing

  • Real workloads: Control loops, sensor fusion, manipulator commands, lidar scans
  • Scale testing: node counts 0-20 and background-topic counts 0-10 (scheduler_ipc_latency); 1-8 producers and 1-8 consumers (scalability_benchmark, all_paths_latency stress scenarios)
  • Topology coverage: Same-thread, cross-thread and cross-process, 1:1 through N:N
  • Contention: Multi-producer and multi-consumer paths measured under contention

Executive Summary

send() costs tens of nanoseconds for typical robotics messages.

Measured with robotics_messages_benchmark on an Intel Core i7-10750H (6C/12T, powersave governor), 50,000 iterations per message type after 5,000 warmup iterations — except LaserScan, which runs one fifth of each (10,000 iterations after 1,000 warmup), so its p99 rests on one fifth the samples the other rows do. These are the four message types the benchmark actually runs:

⚠️What these numbers are, and what they are not

robotics_messages_benchmark times tx.send() enqueue cost only. A cross-thread consumer drains in the background and no sample waits for delivery, so these are not end-to-end latencies. The binary says so on every run:

SUMMARY BY MESSAGE TYPE — send() ENQUEUE COST, not end-to-end latency

An end-to-end control loop additionally pays the receive side, the node's own compute, and the scheduler's jitter — none of which is measured here. Do not read a figure below as a control-loop guarantee, and do not divide a control period by it to get "headroom": the benchmark's own real-time section prints gate not discriminating on every such comparison for exactly that reason.

For end-to-end numbers see Performance, which reports one-way publish→receive latency.

Measured with robotics_messages_benchmark on an Intel Core i7-10750H (6C/12T, powersave governor), 50,000 iterations after 5,000 warmup iterations — except LaserScan, which runs 10,000 (benchmark_laserscan(iterations / 5)).

Message TypeSizesend() mediansend() p99Sustained publish rate
CmdVel16 B75 ns135 ns12.14M msg/s
Imu304 B121 ns235 ns7.46M msg/s
JointCommand928 B135 ns226 ns6.89M msg/s
LaserScan1480 B210 ns283 ns4.42M msg/s

"Sustained publish rate" is wall-clock over the measured loop, including batch drain-waits. It is the rate this one producer/consumer pair achieved on that host — not a bus capacity, and not additive across publishers.

📝Reproducing these figures
cargo build --release --bin robotics_messages_benchmark
./target/release/robotics_messages_benchmark

The medians above reproduce, and are conservative: on the same CPU model with the performance governor, four runs gave medians of 50–82 ns (CmdVel), 64–74 ns (Imu), 73–115 ns (JointCommand) and 97–194 ns (LaserScan) — at or below the published figures.

The sustained-rate column did not reproduce. The same four runs peaked at 7.00M (CmdVel), 4.53M (Imu), 3.33M (JointCommand) and 1.46M msg/s (LaserScan) — 1.6x to 3.0x below the table, with the gap widening as messages get larger. Those runs were on a loaded desktop, and this metric is wall-clock, so load depresses it directly; that is enough to explain some of the gap but not obviously all of it. Treat the rate column as an upper bound observed on an idle machine rather than as a figure you should expect to see. Tracked in softmata/horus#176.


Performance Highlights

Key Findings

  • Tens of nanoseconds to enqueue a message up to 1.5 KB
  • Serde integration works with complex nested structs
  • Graceful scaling with message size (predictable, roughly linear in payload)
  • Enqueue cost is far below any robotics control period — small enough that it is not the term that decides whether a loop meets its deadline

Production Readiness

  • Real-time control: 75 ns to enqueue a CmdVel; the loop's deadline budget is spent on compute, the receive side and scheduling, not on send()
  • Sensor fusion: 304-byte Imu messages enqueue in 121 ns median, 235 ns p99
  • Manipulator control: kilobyte-scale JointCommand payloads at 135 ns median
  • Multi-robot systems: millions of messages/s from a single producer/consumer pair on one host

Detailed Results

Every figure in this section is send() enqueue cost, as described in the Executive Summary. "Iterations" is the count that message type actually runs, which is not the same for all four.

CmdVel (Motor Control Command)

Use Case: Real-time motor control @ 1000Hz Size: 16 bytes

send() median:           75 ns
send() p99:              135 ns
Sustained publish rate:  12.14M msg/s
Iterations:              50,000

Analysis: 16 bytes enqueues in well under a microsecond. At a 1000 Hz control period, send() is a rounding error against the 1 ms budget — the loop's timing is decided by the receive side, the node's compute and the scheduler, not by this number.


Imu (Inertial Measurement Unit)

Use Case: Orientation and acceleration @ 500Hz Size: 304 bytes (size_of; 296 bytes declared)

send() median:           121 ns
send() p99:              235 ns
Sustained publish rate:  7.46M msg/s
Iterations:              50,000

Analysis: Complex nested arrays and three 9-element (3x3) covariance matrices, still enqueued in nanoseconds. Serde handling of the nested structure adds no visible cost over a flat payload of the same size.


JointCommand (Multi-DOF Control)

Use Case: Manipulator joint control @ 500Hz Size: 928 bytes (size_of; 1032 bytes declared)

send() median:           135 ns
send() p99:              226 ns
Sustained publish rate:  6.89M msg/s
Iterations:              50,000

Analysis: Kilobyte-scale command payloads enqueue in roughly the same time as the 304-byte Imu, so per-message overhead dominates the per-byte copy at this size.


LaserScan (2D Lidar Data)

Use Case: 2D lidar sensor data @ 10-40Hz Size: 1480 bytes

send() median:           210 ns
send() p99:              283 ns
Sustained publish rate:  4.42M msg/s
Iterations:              10,000

Analysis: At 1.5 KB the payload copy starts to show — the median is about 2.8x CmdVel's for 92x the bytes. This type runs 10,000 iterations, not 50,000 (benchmark_laserscan(iterations / 5)).


Comparison with traditional frameworks

Latency Comparison

Measurement Note: HORUS values below are send-only (one-direction). For round-trip (send+receive), approximately double them. The DDS rows are published reference values (64-byte messages, same-process, sourced to REP 2014 and the Eclipse iceoryx benchmarks) — they are not measured on this machine, and no benchmark in the repository produces them: dds_comparison_benchmark was deleted for manufacturing competitor percentiles from two constants.

FrameworkMedianp99
HORUS Topic (same process, 1:1)63 ns93 ns
HORUS Topic (cross process, 1:1)151 ns181 ns
iceoryx (C++)~80 ns~200 ns
CycloneDDS~1,500 ns~5,000 ns
FastDDS~2,000 ns~8,000 ns
ROS2 Default~5,000 ns~20,000 ns

Performance Advantage: against the ROS2 default reference, HORUS is roughly 33x faster cross-process and 79x faster same-process; against FastDDS, roughly 13x and 32x.


Latency by Message Size

Measurement Note: The HORUS column is send() enqueue cost measured by robotics_messages_benchmark with an auto-selected Topic backend — no sample waits for delivery, so it is not even a full one-way latency. Sizes are size_of at runtime.

The ROS 2 column divides that send-only figure by ROS 2's ~5 µs REP 2014 reference, which is an end-to-end number we did not measure. The two sides are therefore not like-for-like and the ratios are indicative, not a benchmark result. For a one-way-to-one-way comparison use the cross-process row above (151 ns), which gives roughly 33x.

Message SizeMessage Typesend() mediansend() p99Sustained publish ratevs ROS2 default (~5 μs)
16 BCmdVel75 ns135 ns12.14 M msg/s~67x faster
304 BImu121 ns235 ns7.46 M msg/s~41x faster
928 BJointCommand135 ns226 ns6.89 M msg/s~37x faster
1,480 BLaserScan210 ns283 ns4.42 M msg/s~24x faster

Observation: Enqueue cost grows far more slowly than message size — 92x more bytes costs under 3x — because the per-message overhead dominates the per-byte copy across this whole range.


Python Performance

The HORUS Python bindings (PyO3) call directly into the Rust shared memory layer, avoiding pickle serialization overhead. Python nodes and Rust nodes communicate through the same shared memory, enabling cross-language interoperability with minimal overhead.

Why Python HORUS is Fast:

  1. Zero-copy via Rust core: Python bindings call directly into Rust shared memory
  2. No pickle overhead: Messages use efficient binary serialization
  3. PyO3 efficiency: Minimal FFI overhead between Python and Rust

No published Python figures. Every number on this page comes from the Rust-side benchmarks; the repository publishes no reference latency or throughput figures for the Python bindings, so this section quotes none. To measure them on your own hardware run python3 horus_py/benchmarks/bench_python.py (message round-trip, node tick overhead, zero-copy image conversion, multi-node scheduler throughput) or python3 horus_py/benchmarks/research_bench_python.py --duration 30 for sustained runs with a full p50/p95/p99/p99.9 distribution and CSV/JSON output.

TensorPool

HORUS TensorPool provides shared memory tensors optimized for ML/AI workloads. Pre-mapped shared memory means no malloc() on the hot path. Zeroing is not avoided, only moved: return_slot() scrubs a slot's data region before it returns to the free list, so the cost scales with tensor size (see the figures in TensorPool).

from horus import TensorPool
import numpy as np

# Create pool
pool = TensorPool(12345)  # pool_id

# Allocate tensor (pre-mapped shared memory)
h = pool.alloc([1024, 1024], 'float32')

# Zero-copy NumPy view
arr = h.numpy()  # No data copied

# Cross-process sharing via shared memory
descriptor = h.to_descriptor()

Key Advantages:

  • Cross-process sharing via shared memory
  • Pre-allocated pool — no malloc on hot path
  • Refcounted handles — safe concurrent access
  • Zero-copy NumPy.numpy() returns view

Running Rust Benchmarks

Quick Run

cd horus
cargo run --release -p horus_benchmarks --bin robotics_messages_benchmark

Available Benchmarks

BinaryDescription
robotics_messages_benchmarkIPC latency with real robotics message types
all_paths_latencyTopic latency across all backend routes (SpscShm, MpscShm, PodShm, raw-atomic floor)
cross_process_benchmarkCross-process shared memory IPC
scalability_benchmarkScaling with producer/consumer thread counts
determinism_benchmarkExecution determinism and jitter
topic_probeOne POD path, ~2s — the fast loop for hot-path work
competitor_comparisonHORUS versus raw UDP loopback (single-thread; see the file header)
iceoryx2_comparisonComparison with iceoryx2 — requires --features iceoryx2

Run any benchmark with:

cargo run --release -p horus_benchmarks --bin <name>

# JSON output for CI/regression tracking. Accepted by all_paths_latency,
# cross_process_benchmark, determinism_benchmark, robotics_messages_benchmark
# and scalability_benchmark only.
cargo run --release -p horus_benchmarks --bin <name> -- --json results.json

# competitor_comparison writes CSV instead
cargo run --release -p horus_benchmarks --bin competitor_comparison -- --csv comparison.csv

# topic_probe prints per-repetition lines instead
cargo run --release -p horus_benchmarks --bin topic_probe -- --raw

topic_probe, competitor_comparison and iceoryx2_comparison do not parse --json: the first two scan the command line only for their own flags, and iceoryx2_comparison never reads it at all. Passing -- --json results.json to one of them produces an ordinary run, no error and no file, so a CI step that collects the file has to check that it exists.

Criterion micro-benchmarks:

cd horus
cargo bench -p horus_benchmarks

Expected Output

╔══════════════════════════════════════════════════════════════════╗
║        HORUS Robotics Message Types Benchmark                    ║
╠══════════════════════════════════════════════════════════════════╣
║  Testing real-world robotics message latency (REP 2014)          ║
╚══════════════════════════════════════════════════════════════════╝

Platform: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz (12 cores)
Iterations: 50000
Warmup: 5000

╔═════════════════════════════════════════════════════════════════════════════╗
║ Message Type    │ Size (bytes) │ Typical Rate │ Use Case                    ║
╠═════════════════════════════════════════════════════════════════════════════╣
║ CmdVel          │           16 │ 1000+ Hz     │ Velocity control commands   ║
║ Imu             │          296 │ 500+ Hz      │ IMU sensor fusion           ║
║ LaserScan       │         1480 │ 10-40 Hz     │ 2D lidar navigation         ║
║ JointCommand    │         1032 │ 500+ Hz      │ Manipulator control         ║
╚═════════════════════════════════════════════════════════════════════════════╝

[Topic] Running benchmarks — timing tx.send() enqueue cost only
        (cross-thread consumer drains in the background; no sample
         waits for delivery, so these are NOT end-to-end latencies)
─────────────────────────────────────────────────
  CmdVel              16 bytes │ median:      75ns │ p99:     135ns │ CV: 1.3146
  Imu                304 bytes │ median:     121ns │ p99:     235ns │ CV: 1.1833
  LaserScan         1480 bytes │ median:     210ns │ p99:     283ns │ CV: 0.6795
  JointCommand       928 bytes │ median:     135ns │ p99:     226ns │ CV: 0.8705

The run also prints a SUMMARY BY MESSAGE TYPE table with throughput and a REAL-TIME SUITABILITY ANALYSIS block. The sizes in the banner table (296 B for Imu, 1032 B for JointCommand) are hard-coded labels in the benchmark header; the per-type result lines print the real std::mem::size_of values (304 B and 928 B).


Use Case Selection

Message Type Guidelines

CmdVel — 16 B, 75 ns median / 135 ns p99

  • Motor control @ 1000Hz
  • Real-time actuation commands
  • Safety-critical control loops

Imu — 304 B, 121 ns median / 235 ns p99

  • High-frequency sensor fusion @ 500Hz
  • State estimation pipelines
  • Orientation tracking

JointCommand — 928 B, 135 ns median / 226 ns p99

  • Multi-DOF manipulator control @ 500Hz
  • Coordinated joint trajectories
  • Arm and gripper command streams

LaserScan — 1480 B, 210 ns median / 283 ns p99

  • 2D lidar @ 10-40Hz
  • Obstacle detection
  • SLAM front-end

Performance Characteristics

Strengths

  1. Sub-microsecond latency for messages up to 1.5KB
  2. Consistent performance across message types (low variance)
  3. Graceful scaling with message size
  4. Production-ready throughput with large headroom
  5. Serde integration handles complex nested structs efficiently

Additional Notes

  • Complex structs (Imu with three 9-element covariance matrices): 121 ns median — still sub-microsecond
  • Large messages (LaserScan at 1480 B): 210 ns median — a 92x size increase over CmdVel costs under 3x latency

Real-World Applications

ApplicationMessageFrequencyHORUS medianROS2 default (REP 2014 ref)Speedup
Motor controlCmdVel (16 B)1000 Hz75 ns~5 μs~67x
Sensor fusionImu (304 B)500 Hz121 ns~5 μs~41x
Manipulator controlJointCommand (928 B)500 Hz135 ns~5 μs~37x
Lidar SLAMLaserScan (1480 B)10-40 Hz210 ns~5 μs~24x

Methodology

Benchmark Pattern: Send-Side and One-Way

HORUS measures latency in one direction only — no acknowledgement leg is sent:

Loading diagram...
Send-side and one-way latency measurement

Why one-way?

  • Comparable: matches the one-way figures published by REP 2014 and the iceoryx benchmarks
  • No return-path bias: a round-trip number blends two directions plus the consumer's wake-up cost
  • Cross-core: producer and consumer are pinned to separate physical cores, so cache-coherency cost is included
  • Conservative for cross-process: the timestamp is written before send() and read after recv(), so serialization, IPC and deserialization are all inside the measurement

What we measure:

  • send — producer-side send() latency via RDTSC. The subtracted overhead is the minimum of 10,000 back-to-back rdtsc()/rdtscp() pairs with no work between them, calibrated once per process (same-process scenarios)
  • one-way — producer → consumer latency from an RDTSC timestamp carried in CmdVel.timestamp_ns (cross-process scenarios)
  • broadcast — one-way latency on latest-value PodShm paths, plus read freshness and skip-ahead counts

What we DON'T measure:

  • Round-trip as the headline number. The offset-free cross-process scenario (Topic_cross_process_oneway_pingpong) does send a reply — that is how it cancels the two cores' TSC offset, NTP-style — but it reports (fwd + rev) / 2, a one-way figure. rtt / 2 is printed beside it, labelled as a halved round trip, and is the larger of the two because it also carries the responder's recv→send turnaround.
  • Burst throughput (no backpressure)
  • Same-core communication (unrealistic for multi-process IPC)

Test Environment

  • Build: cargo build --release with full optimizations
  • CPU Governor: performance mode recommended; the figures quoted on this page were captured under powersave, which inflates cross-process latencies
  • CPU Affinity: Producer and consumer pinned to separate physical cores (all_paths_latency reads thread_siblings_list to pick five distinct physical cores, falling back to 0/2/4/6/8 only when the kernel will not report topology)
  • Process Isolation: Dedicated topics per benchmark
  • Warmup: 5,000 iterations discarded before measurement (10,000 for determinism_benchmark; 1,000 for the LaserScan case in robotics_messages_benchmark)
  • Measurement: RDTSC (cycle-accurate timestamps)

Message Realism

  • Actual HORUS library message types
  • Serde serialization (production path)
  • Realistic field values and sizes
  • Complex nested structures (Imu, LaserScan, JointCommand)

Statistical Methodology

  • 50,000 iterations per message type (robotics_messages_benchmark, override with --iterations) — except LaserScan, which is called with iterations / 5, so 10,000 by default; 100,000 samples per scenario (all_paths_latency, determinism_benchmark)
  • Median, p95, p99, p99.9 latency tracking
  • Tukey IQR outlier counting (1.5x fence), reported as a diagnostic only — every published statistic is computed from the full, unfiltered sample set, because the fence deletes exactly the preemptions and page faults that constitute the tail
  • Bootstrap 95% confidence intervals (10K resamples), also over the full sample set
  • Variance tracking (min/max ranges, coefficient of variation)
  • Multiple message sizes

Measurement Details

RDTSC Calibration:

  • Null cost (back-to-back rdtsc): ~36 cycles
  • Target on modern x86_64: 20-30 cycles
  • Timestamp embedded directly in message payload

Cross-Core Testing:

  • Producer and consumer on different CPU cores
  • Simulates real multi-process robotics systems
  • Includes cache coherency overhead (~60 cycles theoretical minimum)

Scheduler Performance

Scheduler Features

Key capabilities:

  • Execution classes: .compute() moves long-running nodes off the tick path, .async_io() for blocking I/O, .rate() and .order() for per-node pacing and ordering
  • Fault Tolerance: per-node FailurePolicyFatal, Restart { max_restarts, initial_backoff }, Skip { max_failures, cooldown }, Ignore
  • Deterministic mode: opt-in sequential execution with reproducible runs — Scheduler::new().deterministic(true) (default is false)
  • Safety Monitoring: tick budgets, deadline-miss policies (Miss), watchdogs and a blackbox recorder

Scalability Performance

The Criterion bench scheduler_ipc_latency sweeps node counts 0/1/5/10/20 and topic counts 0/1/5/10. Larger node and topic counts are not benchmarked in this repository.

Topic scaling (send + recv latency, Intel Core i7-10750H, powersave governor):

Topicsp50p99
166 ns80 ns
1065 ns88 ns

Only the counts the bench actually sweeps are listed. bench_latency_by_topic_count iterates [0, 1, 5, 10], so rows for 50, 100, 500 and 1,000 topics would be numbers nobody measured — they were on this page, and they are gone.

Key Insights:

  • Topic lookup does not degrade across the range that is measured (1 to 10 topics). Whether it stays flat at 1,000 is untested here; measure it if you depend on it
  • The repository README reports near-linear scheduler scaling to 100 nodes (~14% degradation) and O(1) topic lookup to 1,000 topics, without attributing either to a machine. No benchmark in the repository produces either figure — the largest sweeps are 20 nodes and 10 topics — so treat both as unsourced until they are regenerated
  • Node-scaling timings are dominated by OS scheduling noise under the powersave governor and vary substantially run-to-run; measure on your own hardware with the performance governor before quoting numbers
cargo bench -p horus_benchmarks --bench scheduler_ipc_latency

Real-Time Performance

Real-Time Node Configuration

HORUS provides real-time facilities for applications with explicit timing constraints:

RT Features:

  • Tick budget enforcement: .budget(Duration) per node, reporting a BudgetViolation when a tick overruns
  • Deadline handling: .deadline(Duration) with .on_miss(Miss::Warn | Miss::Skip | Miss::SafeMode | Miss::Stop), plus Scheduler::max_deadline_misses()
  • Failure policies: per-node FailurePolicy::Fatal, Restart { max_restarts, initial_backoff }, Skip { max_failures, cooldown }, Ignore
  • Watchdog Timers: .watchdog(Duration) on the scheduler or on individual nodes, to detect hung or crashed nodes

Full Safety-Monitoring Configuration

Running with full safety monitoring enabled:

use horus::prelude::*;

let mut scheduler = Scheduler::new()
    .tick_rate(1000_u64.hz())
    .prefer_rt()
    .watchdog(10_u64.ms())
    .max_deadline_misses(100);

scheduler
    .add(motor_controller)
    .order(0)
    .rate(1000_u64.hz())
    .budget(200_u64.us())
    .on_miss(Miss::SafeMode)
    .failure_policy(FailurePolicy::Fatal)
    .build()?;

No published overhead figures. The repository contains no benchmark that measures watchdog resolution, emergency-stop time, deadline-detection jitter or budget-tracking overhead, so this page does not quote any. For scheduler timing behaviour run cargo bench -p horus_benchmarks --bench scheduler_jitter, which measures RT tick interval jitter at 500 Hz with and without competing compute nodes.


All-Routes Latency

HORUS automatically selects the backend from the producer/consumer counts and whether the message type is POD. Every topic is shared-memory backed, so the same-thread, cross-thread and cross-process scenarios below can resolve to the same backend — what changes between them is where the two ends run, not the transport. This benchmark measures the latency of each automatically-selected route.

Benchmark Results

Measured with all_paths_latency on an Intel Core i7-10750H (6C/12T, powersave governor), 100K samples per scenario, RDTSC timing with calibrated overhead subtraction. The benchmark defines no target values — these are the scenario names and columns it actually reports.

ScenarioTypeBackendp50p99
SameThreadsendSpscShm20 ns26 ns
CrossThread-1P1CsendSpscShm63 ns93 ns
CrossThread-MP1CsendMpscShm226 ns429 ns
CrossThread-1PMCsendPodShm74 ns120 ns
CrossThread-MPMCsendPodShm190 ns354 ns
CrossProc-1P1Cone-waySpscShm151 ns181 ns
CrossProc-2P1Cone-wayMpscShm279 ns374 ns
CrossProc-1PMCone-wayPodShm191 ns209 ns
CrossProc-PodShmbroadcastPodShm223 ns270 ns
RawAtomic (hardware floor)one-wayraw shm79 ns102 ns

MP1C/MPMC scenarios are contended (2 producers, or 2 producers and 2 consumers). Framework overhead is the gap to the RawAtomic floor — 72 ns for cross-process 1:1.

Key Achievements

  • 20 ns same-thread and 63 ns cross-thread for uncontended 1:1 paths
  • ~200 ns for contended multi-producer same-process paths (226 ns MP1C, 190 ns MPMC)
  • Sub-200ns for cross-process 1:1 (151 ns)
  • ~280 ns for multi-producer cross-process (2 producers → 1 consumer)
  • Zero configuration — optimal path selected automatically
  • Seamless migration — path upgrades transparently as topology changes

Running the Benchmark

cd horus
cargo build --release -p horus_benchmarks
./target/release/all_paths_latency

Summary

HORUS provides production-grade performance for real robotics applications:

Automatic Path Selection (all_paths_latency, p50):

  • 20 ns — Same-thread (SpscShm)
  • 63 ns — Cross-thread, 1:1 (SpscShm)
  • 151 ns — Cross-process, 1:1 (SpscShm)
  • 279 ns — Cross-process, 2 producers → 1 consumer (MpscShm)
  • 223 ns — Cross-process broadcast, N:N (PodShm)
  • 79 ns — Raw shared-memory atomic (hardware floor)

Robotics Message Types (robotics_messages_benchmark, median):

  • 75 ns — CmdVel, 16 B (motor control)
  • 121 ns — Imu, 304 B (sensor fusion)
  • 135 ns — JointCommand, 928 B (manipulator control)
  • 210 ns — LaserScan, 1480 B (2D lidar)

Ready for production deployment in demanding robotics applications requiring real-time performance with complex data types.


Next Steps

Build faster. Debug easier. Deploy with confidence.