mirror of
https://github.com/esphome/esphome.git
synced 2025-10-13 15:23:49 +01:00
[core] Optimize looping_components_ with FixedVector to save flash
This commit is contained in:
@@ -340,8 +340,8 @@ void Application::calculate_looping_components_() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-reserve vector to avoid reallocations
|
// Initialize FixedVector with exact size - no reallocation possible
|
||||||
this->looping_components_.reserve(total_looping);
|
this->looping_components_.init(total_looping);
|
||||||
|
|
||||||
// Add all components with loop override that aren't already LOOP_DONE
|
// Add all components with loop override that aren't already LOOP_DONE
|
||||||
// Some components (like logger) may call disable_loop() during initialization
|
// Some components (like logger) may call disable_loop() during initialization
|
||||||
|
@@ -472,7 +472,7 @@ class Application {
|
|||||||
// - When a component is enabled, it's swapped with the first inactive component
|
// - When a component is enabled, it's swapped with the first inactive component
|
||||||
// and active_end_ is incremented
|
// and active_end_ is incremented
|
||||||
// - This eliminates branch mispredictions from flag checking in the hot loop
|
// - This eliminates branch mispredictions from flag checking in the hot loop
|
||||||
std::vector<Component *> looping_components_{};
|
FixedVector<Component *> looping_components_{};
|
||||||
#ifdef USE_SOCKET_SELECT_SUPPORT
|
#ifdef USE_SOCKET_SELECT_SUPPORT
|
||||||
std::vector<int> socket_fds_; // Vector of all monitored socket file descriptors
|
std::vector<int> socket_fds_; // Vector of all monitored socket file descriptors
|
||||||
#endif
|
#endif
|
||||||
|
@@ -159,6 +159,50 @@ template<typename T, size_t N> class StaticVector {
|
|||||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Fixed-capacity vector - allocates once at runtime, never reallocates
|
||||||
|
/// This avoids std::vector template overhead (_M_realloc_insert, _M_default_append)
|
||||||
|
/// when size is known at initialization but not at compile time
|
||||||
|
template<typename T> class FixedVector {
|
||||||
|
private:
|
||||||
|
T *data_{nullptr};
|
||||||
|
size_t size_{0};
|
||||||
|
size_t capacity_{0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
FixedVector() = default;
|
||||||
|
|
||||||
|
~FixedVector() {
|
||||||
|
if (data_ != nullptr) {
|
||||||
|
delete[] data_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable copy to avoid accidental copies
|
||||||
|
FixedVector(const FixedVector &) = delete;
|
||||||
|
FixedVector &operator=(const FixedVector &) = delete;
|
||||||
|
|
||||||
|
// Allocate capacity - can only be called once on empty vector
|
||||||
|
void init(size_t n) {
|
||||||
|
if (data_ == nullptr && n > 0) {
|
||||||
|
data_ = new T[n];
|
||||||
|
capacity_ = n;
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add element (no reallocation - must have initialized capacity)
|
||||||
|
void push_back(const T &value) {
|
||||||
|
if (size_ < capacity_) {
|
||||||
|
data_[size_++] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const { return size_; }
|
||||||
|
|
||||||
|
T &operator[](size_t i) { return data_[i]; }
|
||||||
|
const T &operator[](size_t i) const { return data_[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
/// @name Mathematics
|
/// @name Mathematics
|
||||||
|
Reference in New Issue
Block a user