[F52.1] mxaccess-codec: BytesMut output buffer for write encoder
Adds `write_message::encode_to_bytes_mut` (and the timestamped variant) returning a freshly-allocated `BytesMut`. Allocation count is identical to `encode` (2 allocs/op for fixed-width scalars); the benefit is downstream — consumers can `BytesMut::split_to` / `freeze` and forward the body bytes to a wire-level sink without an intermediate copy. The body builders (`encode_boolean` / `encode_fixed` / `encode_variable` / `encode_array`) were refactored to fill a pre-sized `&mut [u8]` rather than each allocating their own `Vec<u8>`. The dispatcher computes the body size up front via small `*_body_size` helpers and resizes the destination buffer (Vec or BytesMut) once. This is also the prerequisite refactor for F52.3. Bench delta in `design/M6-bench-baseline.md` § F52.1; existing `encode` row unchanged at 2 allocs/op. All 265 round-trip tests unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,7 +39,7 @@ use std::alloc::{GlobalAlloc, Layout, System};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use mxaccess_codec::{
|
||||
MxReferenceHandle, NmxSubscriptionMessage, write_message, write_message::WriteValue,
|
||||
write_message, write_message::WriteValue, MxReferenceHandle, NmxSubscriptionMessage,
|
||||
};
|
||||
|
||||
// ---- counting allocator -------------------------------------------------
|
||||
@@ -202,6 +202,18 @@ fn bench_write_string() -> Row {
|
||||
})
|
||||
}
|
||||
|
||||
// F52.1 — `BytesMut` output. Same alloc count as `encode`; the benefit is
|
||||
// downstream zero-copy (consumers can `split_to` / `freeze` without copying
|
||||
// the body bytes).
|
||||
fn bench_write_int32_bytes_mut() -> Row {
|
||||
let handle = make_handle();
|
||||
let value = WriteValue::Int32(42);
|
||||
measure("write_message::encode_to_bytes_mut (Int32)", 10_000, || {
|
||||
let bytes = write_message::encode_to_bytes_mut(&handle, &value, 0, 0).unwrap();
|
||||
std::hint::black_box(bytes);
|
||||
})
|
||||
}
|
||||
|
||||
fn bench_subscription_decode() -> Row {
|
||||
// Build a single-record DataUpdate body once; decode N times.
|
||||
let body = build_data_update_int32_body(42);
|
||||
@@ -262,6 +274,7 @@ fn main() {
|
||||
bench_write_double(),
|
||||
bench_write_bool(),
|
||||
bench_write_string(),
|
||||
bench_write_int32_bytes_mut(),
|
||||
bench_handle_from_names(),
|
||||
bench_subscription_decode(),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user