mirror of
https://github.com/esphome/esphome.git
synced 2025-10-13 23:33:48 +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
|
||||
this->looping_components_.reserve(total_looping);
|
||||
// Initialize FixedVector with exact size - no reallocation possible
|
||||
this->looping_components_.init(total_looping);
|
||||
|
||||
// Add all components with loop override that aren't already LOOP_DONE
|
||||
// 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
|
||||
// and active_end_ is incremented
|
||||
// - 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
|
||||
std::vector<int> socket_fds_; // Vector of all monitored socket file descriptors
|
||||
#endif
|
||||
|
@@ -159,6 +159,50 @@ template<typename T, size_t N> class StaticVector {
|
||||
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
|
||||
|
Reference in New Issue
Block a user