mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 23:21:54 +00:00 
			
		
		
		
	Merge branch 'loop_fix_vec' into memory_api
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 | ||||||
|   | |||||||
| @@ -478,7 +478,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 | ||||||
|   | |||||||
| @@ -162,6 +162,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