8000
Skip to content

[api] Avoid object_id string allocations for all entity info messages - #10260

Merged
jesserockz merged 2 commits into
devfrom
object_id_alloc
Aug 20, 2025
Merged

[api] Avoid object_id string allocations for all entity info messages#10260
jesserockz merged 2 commits into
devfrom
object_id_alloc

Conversation

@bdraco
@bdraco bdraco commented Aug 16, 2025
Copy link
Copy Markdown
Member

What does this implement/fix?

This PR optimizes the API to avoid allocating temporary strings for object_id when sending entity information. Since object_id is sent for every entity on each Home Assistant reconnect (which can be 10s-100s of entities), eliminating these allocations is worth the 80 bytes of flash overhead.

The optimization adds a get_object_id_ref_for_api_() method that returns a StringRef for static object_ids (the common case), only falling back to allocation for dynamic object_ids (when MAC suffix is enabled without own name).

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Code quality improvements to existing code or addition of tests
  • Other

Related issue or feature (if applicable): N/A

Pull request in esphome-docs with documentation (if applicable): N/A (internal optimization, no user-facing changes)

Test Environment

  • ESP32
  • ESP32 IDF
  • ESP8266
  • RP2040
  • BK72xx
  • RTL87xx
  • nRF52840

Example entry for config.yaml:

# No configuration changes needed - this is an internal optimization

Checklist:

  • The code change is tested and works locally.
  • Tests have been added to verify that the new code works (under tests/ folder).

If user exposed functionality or configuration variables are added/changed:

  • N/A - Internal optimization only

Additional Context:

Performance Impact:

  • Flash: +80 bytes (1205702 → 1205782 bytes)
  • RAM: Saves one temporary string allocation per entity on every API connection
  • Benefit: For a typical setup with 50-100 entities, this eliminates 50-100 temporary allocations on each Home Assistant reconnect

Why This Trade-off Makes Sense:

Trading 80 bytes of flash for avoiding 10s-100s of heap allocations per Home Assistant reconnect is a clear win because:

  • Flash is a one-time cost paid at compile time
  • Heap allocations happen repeatedly at runtime on every reconnect
  • Reducing heap fragmentation improves long-term stability
  • Less allocation overhead means faster API connection establishment
  • The flash cost is minimal compared to the runtime benefit

Implementation:

  • Added protected get_object_id_ref_for_api_() method to EntityBase
  • Returns StringRef for static object_ids (most entities)
  • Returns empty StringRef for dynamic cases (MAC suffix without own name)
  • API connection uses this to avoid allocation when possible
  • Follows established _for_api_() pattern used elsewhere in the codebase
  • Method is protected with friend access to allow future changes without breaking external components

@github-actions
Copy link
Copy Markdown
Contributor

To use the changes in this PR:

# Clone the repository:
git clone https://github.com/esphome/esphome
cd esphome

# Checkout the PR branch:
git fetch origin pull/10260/head:object_id_alloc
git checkout object_id_alloc

# Install the development version:
script/setup

# Activate the development version:
source venv/bin/activate

Now you can run esphome as usual to test the changes in this PR.


(Added by the PR bot)

@bdraco
bdraco commented Aug 16, 2025
Copy link
Copy Markdown
Member Author

needs to be tested on a real esp32 since host platform doesn't support this path as it doesn't get the mac so I can't make an integration test

@bdraco bdraco changed the title Avoid object_id string allocations for all entity info API messages [api] Avoid object_id string allocations for all entity info API messages Aug 16, 2025
@bdraco bdraco changed the title [api] Avoid object_id string allocations for all entity info API messages [api] Avoid object_id string allocations for all entity info messages Aug 16, 2025
@bdraco
bdraco commented Aug 18, 2025
Copy link
Copy Markdown
Member Author

tested on esp32

@bdraco
bdraco marked this pull request as ready for review August 18, 2025 02:51
Copilot AI review requested due to automatic review settings August 18, 2025 02:51
@bdraco
bdraco requested a review from a team as a code owner August 18, 2025 02:51
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR optimizes the API by eliminating temporary string allocations for object IDs when sending entity information to Home Assistant. The optimization adds a new method that returns a StringRef for static object IDs (the common case) while only falling back to allocation for dynamic object IDs when MAC suffix is enabled without own name.

  • Adds a get_object_id_ref_for_api_() method to EntityBase that returns StringRef for static object_ids
  • Updates API connection to use the new method to avoid allocations when possible
  • Trades 80 bytes of flash for eliminating 10s-100s of heap allocations per Home Assistant reconnect

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
esphome/core/entity_base.h Adds forward declaration for APIConnection friend access and declares the new optimization method
esphome/core/entity_base.cpp Implements the new method and includes StringRef header, refactors existing logic
esphome/components/api/api_connection.h Updates API connection to use the new method for avoiding string allocations

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment thread esphome/core/entity_base.cpp
@jesserockz
jesserockz merged commit 5a1533b into dev Aug 20, 2025
42 checks passed
@jesserockz
jesserockz deleted the object_id_alloc branch August 20, 2025 02:28
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

0