diff --git a/src/core/emsdevicevalue.cpp b/src/core/emsdevicevalue.cpp index c085bd94b..ea5db353e 100644 --- a/src/core/emsdevicevalue.cpp +++ b/src/core/emsdevicevalue.cpp @@ -38,21 +38,23 @@ DeviceValue::DeviceValue(uint8_t device_type, int16_t min, uint32_t max, uint8_t state) - : device_type(device_type) - , tag(tag) - , value_p(value_p) - , type(type) - , options(options) - , options_single(options_single) - , numeric_operator(numeric_operator) + // Initializer list ordered to match the reordered field declarations in + // emsdevicevalue.h (pointers first, then 1-byte block, then 2/4-byte, then std::string) + : value_p(value_p) , short_name(short_name) , fullname(fullname) - , custom_fullname(custom_fullname) + , options(options) + , options_single(options_single) + , device_type(device_type) + , tag(tag) + , type(type) + , state(state) + , numeric_operator(numeric_operator) , uom(uom) , has_cmd(has_cmd) , min(min) , max(max) - , state(state) { + , custom_fullname(custom_fullname) { // calculate #options in options list if (options_single) { options_size = 1; diff --git a/src/core/emsdevicevalue.h b/src/core/emsdevicevalue.h index efa9935f8..c2a5b12db 100644 --- a/src/core/emsdevicevalue.h +++ b/src/core/emsdevicevalue.h @@ -167,23 +167,27 @@ class DeviceValue { DV_NUMOP_MUL50 = -50 }; - uint8_t device_type; // EMSdevice::DeviceType - int8_t tag; // DeviceValueTAG::* + // Layout chosen for compact packing AND cache locality on 32-bit ESP32. + // pointers — 5 × 4 bytes, all naturally aligned void * value_p; // pointer to variable of any type - uint8_t type; // DeviceValueType::* + const char * const short_name; // used in MQTT and API + const char * const * fullname; // used in Web and Console, is translated const char * const ** options; // options as a flash char array const char * const * options_single; // options are not translated - int8_t numeric_operator; - const char * const short_name; // used in MQTT and API - const char * const * fullname; // used in Web and Console, is translated - std::string custom_fullname; // optional, from customization - uint8_t uom; // DeviceValueUOM::* - bool has_cmd; // true if there is a Console/MQTT command which matches the short_name - int16_t min; // min range - uint32_t max; // max range - uint8_t state; // DeviceValueState::* - - uint8_t options_size; // number of options in the char array, calculated at class initialization + // single-byte fields packed together — hot fields, share cache line 0 with the pointers above + uint8_t device_type; // EMSdevice::DeviceType + int8_t tag; // DeviceValueTAG::* + uint8_t type; // DeviceValueType::* + uint8_t state; // DeviceValueState::* + int8_t numeric_operator; // DeviceValueNumOp::* + uint8_t uom; // DeviceValueUOM::* + bool has_cmd; // true if there is a Console/MQTT command which matches the short_name + uint8_t options_size; // number of options in the char array, calculated at class initialization + // wider numeric range fields + int16_t min; // min range + uint32_t max; // max range + // largest member last (cold path: only read during customization save/load and web display) + std::string custom_fullname; // optional, from customization DeviceValue(uint8_t device_type, // EMSdevice::DeviceType int8_t tag, // DeviceValueTAG::*