diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 06ca14411c..566e530a43 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -634,8 +634,8 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, co } std::vector *raw_buffer = buffer.get_buffer(); - std::vector iovs; - iovs.reserve(packets.size()); + this->reusable_iovs_.clear(); + this->reusable_iovs_.reserve(packets.size()); // We need to encrypt each packet in place for (const auto &packet : packets) { @@ -682,11 +682,11 @@ APIError APINoiseFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer, co struct iovec iov; iov.iov_base = buf_start; iov.iov_len = 3 + mbuf.size; // indicator + size + encrypted data - iovs.push_back(iov); + this->reusable_iovs_.push_back(iov); } // Send all encrypted packets in one writev call - return this->write_raw_(iovs.data(), iovs.size()); + return this->write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size()); } APIError APINoiseFrameHelper::write_frame_(const uint8_t *data, uint16_t len) { @@ -1049,8 +1049,8 @@ APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer } std::vector *raw_buffer = buffer.get_buffer(); - std::vector iovs; - iovs.reserve(packets.size()); + this->reusable_iovs_.clear(); + this->reusable_iovs_.reserve(packets.size()); for (const auto &packet : packets) { uint16_t type = packet.message_type; @@ -1099,11 +1099,11 @@ APIError APIPlaintextFrameHelper::write_protobuf_packets(ProtoWriteBuffer buffer struct iovec iov; iov.iov_base = buf_start + header_offset; iov.iov_len = total_header_len + payload_len; - iovs.push_back(iov); + this->reusable_iovs_.push_back(iov); } // Send all packets in one writev call - return write_raw_(iovs.data(), iovs.size()); + return write_raw_(this->reusable_iovs_.data(), this->reusable_iovs_.size()); } uint8_t APIPlaintextFrameHelper::calculate_header_footer_size(uint16_t message_type, uint16_t payload_len) { diff --git a/esphome/components/api/api_frame_helper.h b/esphome/components/api/api_frame_helper.h index 1dbe0ede8e..b5bcfbbfde 100644 --- a/esphome/components/api/api_frame_helper.h +++ b/esphome/components/api/api_frame_helper.h @@ -175,6 +175,9 @@ class APIFrameHelper { uint8_t frame_header_padding_{0}; uint8_t frame_footer_size_{0}; + // Reusable IOV array for write_protobuf_packets to avoid repeated allocations + std::vector reusable_iovs_; + // Receive buffer for reading frame data std::vector rx_buf_; uint16_t rx_buf_len_ = 0;