[api] Optimize protobuf memory usage with fixed-size arrays for Bluetooth UUIDs - #9782
Conversation
|
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#9782
components: [api, bluetooth_proxy]
refresh: 1h(Added by the PR bot) |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## dev #9782 +/- ##
==========================================
- Coverage 59.97% 59.96% -0.01%
==========================================
Files 51 51
Lines 10310 10333 +23
Branches 1382 1387 +5
==========================================
+ Hits 6183 6196 +13
- Misses 3768 3774 +6
- Partials 359 363 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
All works good on all my proxies. Now I need to port it to aioesphomeapi so its in sync |
|
👋 Hi there! I've automatically requested reviews from codeowners based on the files changed in this PR. @OttoWinter, @jesserockz - You've been requested to review this PR as codeowner(s) of 4 file(s) that were modified. Thanks for your time! 🙏 |
There was a problem hiding this comment.
Pull Request Overview
This PR implements a performance optimization for Bluetooth proxy functionality by introducing fixed-size arrays for protobuf messages, specifically targeting Bluetooth UUIDs and service responses to reduce memory allocations during service discovery.
- Extended the protobuf code generator to support
fixed_array_sizeoption for repeated fields, creatingstd::arrayinstead ofstd::vector - Converted Bluetooth UUID fields from dynamic vectors to fixed 2-element arrays and service responses to 1-element arrays
- Added validation to restrict fixed arrays to encode-only (SOURCE_SERVER) messages with optimized code generation for small arrays
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| script/api_protobuf/api_protobuf.py | Adds FixedArrayRepeatedType class and validation logic for fixed-size array support |
| esphome/components/bluetooth_proxy/bluetooth_connection.cpp | Refactors UUID handling to use direct array filling instead of vector operations |
| esphome/components/api/api_pb2.h | Updates protobuf message declarations to use std::array for UUIDs and services |
| esphome/components/api/api_pb2.cpp | Updates generated encode/calculate_size methods to use unrolled array access |
| esphome/components/api/api.proto | Adds fixed_array_size annotations to UUID and service fields |
What does this implement/fix?
This PR implements a critical performance optimization for Bluetooth proxy functionality by introducing support for fixed-size arrays in protobuf messages. Service discovery is the performance bottleneck for all BLE connections, and this optimization directly addresses that by replacing dynamic memory allocations with fixed-size arrays for Bluetooth UUIDs and service responses.
Key Changes:
fixed_array_sizeoption on repeated fieldsstd::vector<uint64_t>tostd::array<uint64_t, 2>std::vector<BluetoothGATTService>tostd::array<BluetoothGATTService, 1>Memory Savings (ESP32 - 32-bit architecture):
For a typical Bluetooth service discovery with 31 UUIDs (1 service + 10 characteristics + 20 descriptors):
Before: Each UUID required its own heap allocation
After: UUIDs embedded directly in their parent structures
Savings: 620 bytes (56% reduction) + 12 bytes from service array = 632 bytes per discovery
Flash savings: 728 bytes (measured reduction in compiled binary size)
This optimization significantly improves BLE connection performance by:
Types of changes
Related issue or feature (if applicable): N/A
Pull request in esphome-docs with documentation (if applicable): N/A (internal implementation detail)
Test Environment
Example entry for
config.yaml:Checklist:
tests/folder).If user exposed functionality or configuration variables are added/changed:
Additional Notes: