mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 01:58:39 +00:00
[api] Inline ProtoVarInt::parse fast path and return consumed in struct
Replace optional<ProtoVarInt> + consumed pointer with ProtoVarIntResult struct that returns value + consumed count directly. This eliminates memory stores through a pointer on the fast path (single-byte varints < 128), keeping everything in registers. The parse() method is now ESPHOME_ALWAYS_INLINE with the multi-byte slow path outlined to parse_slow_(). The common case for protobuf field tags, small enums, booleans, and typical message sizes/types is a simple high-bit check + register return with no function call. Measured on ESP32 (Xtensa): try_read_frame_ grows only +12 bytes (320 → 332) for two inlined parse sites, while eliminating two function calls per message on the hot path.
This commit is contained in:
@@ -2205,7 +2205,7 @@ def build_message_type(
|
||||
|
||||
cpp = ""
|
||||
if decode_varint:
|
||||
o = f"bool {desc.name}::decode_varint(uint32_t field_id, ProtoVarInt value) {{\n"
|
||||
o = f"bool {desc.name}::decode_varint(uint32_t field_id, ProtoVarIntResult value) {{\n"
|
||||
o += " switch (field_id) {\n"
|
||||
o += indent("\n".join(decode_varint), " ") + "\n"
|
||||
o += " default: return false;\n"
|
||||
@@ -2213,7 +2213,9 @@ def build_message_type(
|
||||
o += " return true;\n"
|
||||
o += "}\n"
|
||||
cpp += o
|
||||
prot = "bool decode_varint(uint32_t field_id, ProtoVarInt value) override;"
|
||||
prot = (
|
||||
"bool decode_varint(uint32_t field_id, ProtoVarIntResult value) override;"
|
||||
)
|
||||
protected_content.insert(0, prot)
|
||||
if decode_length:
|
||||
o = f"bool {desc.name}::decode_length(uint32_t field_id, ProtoLengthDelimited value) {{\n"
|
||||
|
||||
Reference in New Issue
Block a user