mirror of
https://github.com/esphome/esphome.git
synced 2025-06-15 06:46:59 +02:00
[globals] Prevent redundant oversized string checks in loop (#9001)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
This commit is contained in:
parent
b7ca6e087a
commit
ce4371a80d
@ -39,7 +39,7 @@ template<typename T> class RestoringGlobalsComponent : public Component {
|
||||
void setup() override {
|
||||
this->rtc_ = global_preferences->make_preference<T>(1944399030U ^ this->name_hash_);
|
||||
this->rtc_.load(&this->value_);
|
||||
memcpy(&this->prev_value_, &this->value_, sizeof(T));
|
||||
memcpy(&this->last_checked_value_, &this->value_, sizeof(T));
|
||||
}
|
||||
|
||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
@ -52,15 +52,15 @@ template<typename T> class RestoringGlobalsComponent : public Component {
|
||||
|
||||
protected:
|
||||
void store_value_() {
|
||||
int diff = memcmp(&this->value_, &this->prev_value_, sizeof(T));
|
||||
int diff = memcmp(&this->value_, &this->last_checked_value_, sizeof(T));
|
||||
if (diff != 0) {
|
||||
this->rtc_.save(&this->value_);
|
||||
memcpy(&this->prev_value_, &this->value_, sizeof(T));
|
||||
memcpy(&this->last_checked_value_, &this->value_, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
T value_{};
|
||||
T prev_value_{};
|
||||
T last_checked_value_{};
|
||||
uint32_t name_hash_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
};
|
||||
@ -85,7 +85,7 @@ template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public C
|
||||
if (hasdata) {
|
||||
this->value_.assign(temp + 1, temp[0]);
|
||||
}
|
||||
this->prev_value_.assign(this->value_);
|
||||
this->last_checked_value_.assign(this->value_);
|
||||
}
|
||||
|
||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
@ -98,13 +98,12 @@ template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public C
|
||||
|
||||
protected:
|
||||
void store_value_() {
|
||||
int diff = this->value_.compare(this->prev_value_);
|
||||
int diff = this->value_.compare(this->last_checked_value_);
|
||||
if (diff != 0) {
|
||||
// Make it into a length prefixed thing
|
||||
unsigned char temp[SZ];
|
||||
|
||||
// If string is bigger than the allocation, do not save it.
|
||||
// We don't need to waste ram setting prev_value either.
|
||||
int size = this->value_.size();
|
||||
// Less than, not less than or equal, SZ includes the length byte.
|
||||
if (size < SZ) {
|
||||
@ -112,13 +111,17 @@ template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public C
|
||||
// SZ should be pre checked at the schema level, it can't go past the char range.
|
||||
temp[0] = ((unsigned char) size);
|
||||
this->rtc_.save(&temp);
|
||||
this->prev_value_.assign(this->value_);
|
||||
}
|
||||
// Always update last_checked_value_ to match current value, even for oversized strings.
|
||||
// This prevents redundant size checks on every loop iteration when a string remains oversized.
|
||||
// Without this, the diff != 0 check would pass repeatedly for the same oversized string,
|
||||
// wasting CPU cycles on size comparisons.
|
||||
this->last_checked_value_.assign(this->value_);
|
||||
}
|
||||
}
|
||||
|
||||
T value_{};
|
||||
T prev_value_{};
|
||||
T last_checked_value_{};
|
||||
uint32_t name_hash_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user