1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-02 19:32:19 +01:00

Avoid object_id string allocations for all entity info API messages

This commit is contained in:
J. Nick Koston
2025-08-16 09:35:12 -04:00
parent 6c5632a0b3
commit 15fca7dea8
3 changed files with 30 additions and 3 deletions

View File

@@ -301,9 +301,15 @@ class APIConnection : public APIServerConnection {
APIConnection *conn, uint32_t remaining_size, bool is_single) { APIConnection *conn, uint32_t remaining_size, bool is_single) {
// Set common fields that are shared by all entity types // Set common fields that are shared by all entity types
msg.key = entity->get_object_id_hash(); msg.key = entity->get_object_id_hash();
// IMPORTANT: get_object_id() may return a temporary std::string // Try to use static reference first to avoid allocation
StringRef static_ref = entity->get_object_id_ref_for_api_();
if (!static_ref.empty()) {
msg.set_object_id(static_ref);
} else {
// Dynamic case - need to allocate
std::string object_id = entity->get_object_id(); std::string object_id = entity->get_object_id();
msg.set_object_id(StringRef(object_id)); msg.set_object_id(StringRef(object_id));
}
if (entity->has_own_name()) { if (entity->has_own_name()) {
msg.set_name(entity->get_name()); msg.set_name(entity->get_name());

View File

@@ -1,6 +1,7 @@
#include "esphome/core/entity_base.h" #include "esphome/core/entity_base.h"
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include "esphome/core/string_ref.h"
namespace esphome { namespace esphome {
@@ -58,6 +59,15 @@ std::string EntityBase::get_object_id() const {
return this->object_id_c_str_; return this->object_id_c_str_;
} }
} }
StringRef EntityBase::get_object_id_ref_for_api_() const {
static constexpr auto EMPTY_STRING_REF = StringRef::from_lit("");
// Return empty for dynamic case (MAC suffix)
if (!this->flags_.has_own_name && App.is_name_add_mac_suffix_enabled()) {
return EMPTY_STRING_REF;
}
// For static case, return the string or empty if null
return this->object_id_c_str_ == nullptr ? EMPTY_STRING_REF : StringRef(this->object_id_c_str_);
}
void EntityBase::set_object_id(const char *object_id) { void EntityBase::set_object_id(const char *object_id) {
this->object_id_c_str_ = object_id; this->object_id_c_str_ = object_id;
this->calc_object_id_(); this->calc_object_id_();

View File

@@ -12,6 +12,11 @@
namespace esphome { namespace esphome {
// Forward declaration for friend access
namespace api {
class APIConnection;
} // namespace api
enum EntityCategory : uint8_t { enum EntityCategory : uint8_t {
ENTITY_CATEGORY_NONE = 0, ENTITY_CATEGORY_NONE = 0,
ENTITY_CATEGORY_CONFIG = 1, ENTITY_CATEGORY_CONFIG = 1,
@@ -81,6 +86,12 @@ class EntityBase {
void set_has_state(bool state) { this->flags_.has_state = state; } void set_has_state(bool state) { this->flags_.has_state = state; }
protected: protected:
friend class api::APIConnection;
// Get object_id as StringRef when it's static (for API usage)
// Returns empty StringRef if object_id is dynamic (needs allocation)
StringRef get_object_id_ref_for_api_() const;
/// The hash_base() function has been deprecated. It is kept in this /// The hash_base() function has been deprecated. It is kept in this
/// class for now, to prevent external components from not compiling. /// class for now, to prevent external components from not compiling.
virtual uint32_t hash_base() { return 0L; } virtual uint32_t hash_base() { return 0L; }