8000
Skip to content

[api] Optimize protobuf decode loop for better performance and maintainability - #10277

Merged
kbx81 merged 2 commits into
devfrom
decode_cleanup
Aug 18, 2025
Merged

[api] Optimize protobuf decode loop for better performance and maintainability#10277
kbx81 merged 2 commits into
devfrom
decode_cleanup

Conversation

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

What does this implement/fix?

Optimizes the protobuf decode loop in ProtoDecodableMessage::decode() by eliminating redundant error handling and improving control flow. The changes result in cleaner, more maintainable code with measurable performance improvements for typical API message sizes.

Key improvements:

  • Replaced error flag + break pattern with early returns, reducing branching overhead
  • Switched from index-based to pointer-based buffer traversal for better compiler optimization
  • Consolidated boundary checks for length-delimited fields
  • Improved error messages with offset reporting instead of index values
  • Reduced flash usage by 224 bytes with no RAM impact

Performance impact:

  • 7.5% faster for small messages (~100 bytes) - typical sensor updates
  • 1.2% faster for medium messages (~1KB) - device state messages
  • All ESPHome API messages are generally under 1400 bytes, so these improvements apply to all real-world usage
  • All improvements are statistically significant (p < 0.05)

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):

  • Part of ongoing API performance optimization efforts

Pull request in esphome-docs with documentation (if applicable):

  • esphome/esphome-docs#

Test Environment

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

Example entry for config.yaml:

# No config changes required - internal optimization only
api:

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:

@github-actions
Copy link
Copy Markdown
Contributor

To use the changes from this PR as an external component, add the following to your ESPHome configuration YAML file:

external_components:
  - source: github://pr#10277
    components: [api]
    refresh: 1h

(Added by the PR bot)

@codecov-commenter
codecov-commenter commented Aug 18, 2025
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.45%. Comparing base (daf8ec3) to head (a922714).
⚠️ Report is 4 commits behind head on dev.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev   #10277   +/-   ##
=======================================
  Coverage   60.45%   60.45%           
=======================================
  Files          51       51           
  Lines       10417    10417           
  Branches     1388     1388           
=======================================
  Hits         6298     6298           
  Misses       3760     3760           
  Partials      359      359           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bdraco
bdraco marked this pull request as ready for review August 18, 2025 04:58
Copilot AI review requested due to automatic review settings August 18, 2025 04:58
@bdraco
bdraco requested a review from a team as a code owner August 18, 2025 04:58
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 protobuf decode loop in ProtoDecodableMessage::decode() by replacing error flag handling with early returns and switching from index-based to pointer-based buffer traversal. The changes improve performance by 1.2-7.5% for typical API message sizes while reducing flash usage by 224 bytes.

Key changes:

  • Replaced error flag + break pattern with immediate returns for cleaner control flow
  • Switched from array indexing to pointer arithmetic for better compiler optimization
  • Consolidated boundary checks and improved error messages with offset reporting

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/components/api/proto.cpp Outdated
Comment thread esphome/components/api/proto.cpp Outdated
Comment thread esphome/components/api/proto.cpp Outdated
Comment thread esphome/components/api/proto.cpp Outdated
Comment thread esphome/components/api/proto.cpp Outdated
Comment thread esphome/components/api/proto.cpp Outdated
@bdraco
bdraco marked this pull request as draft August 18, 2025 05:23
@bdraco
bdraco marked this pull request as ready for review August 18, 2025 13:31
@kbx81 kbx81 left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks! 🍻

@kbx81
kbx81 merged commit 44bd8e5 into dev Aug 18, 2025
30 checks passed
@kbx81
kbx81 deleted the decode_cleanup branch August 18, 2025 21:14
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 20, 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.

5 participants

0