From 9e082edecbe938b45c79e7a1728cb36d1d90bcd5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 7 Mar 2026 13:28:04 -1000 Subject: [PATCH] [api] Outline ProtoByteBuffer reallocation into grow_() The capacity check in reserve()/resize() is the hot path and stays inline. The actual reallocation (make_buffer + memcpy) is a cold path that should be outlined to avoid bloating every call site. Co-Authored-By: Claude Opus 4.6 --- esphome/components/api/proto.cpp | 8 ++++++++ esphome/components/api/proto.h | 12 ++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index 1ca6b702ad..440655a32d 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -8,6 +8,14 @@ namespace esphome::api { static const char *const TAG = "api.proto"; +void ProtoByteBuffer::grow_(size_t n) { + auto new_data = make_buffer(n); + if (this->size_) + std::memcpy(new_data.get(), this->data_.get(), this->size_); + this->data_ = std::move(new_data); + this->capacity_ = n; +} + #ifdef USE_API_VARINT64 optional ProtoVarInt::parse_wide(const uint8_t *buffer, uint32_t len, uint32_t *consumed, uint32_t result32) { diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index 0e861a19d3..1312c87400 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -260,17 +260,12 @@ class ProtoByteBuffer { public: void clear() { this->size_ = 0; } void reserve(size_t n) { - if (n > this->capacity_) { - auto new_data = make_buffer(n); - if (this->size_) - std::memcpy(new_data.get(), this->data_.get(), this->size_); - this->data_ = std::move(new_data); - this->capacity_ = n; - } + if (n > this->capacity_) + this->grow_(n); } void resize(size_t n) { if (n > this->capacity_) - this->reserve(n); + this->grow_(n); this->size_ = n; // no zero-fill } uint8_t *data() { return this->data_.get(); } @@ -278,6 +273,7 @@ class ProtoByteBuffer { size_t size() const { return this->size_; } protected: + void grow_(size_t n); std::unique_ptr data_; size_t size_{0}; size_t capacity_{0};