[Improvement] (MG_Utils): Improve performance in IndexGenerator.

This commit is contained in:
BZLZHH
2025-07-20 15:33:55 +08:00
parent 29a3704463
commit bd2c5e1ebc
+29 -23
View File
@@ -1,52 +1,58 @@
#pragma once #pragma once
#include <vector>
#include <algorithm>
#include <cstdint>
namespace MobileGL { namespace MobileGL {
template <typename IndexType> template <typename IndexType>
class IndexGenerator { class IndexGenerator {
public: public:
IndexGenerator() : next_index_(1) {} explicit IndexGenerator(size_t initial_capacity = 1024)
explicit IndexGenerator(IndexType n) : next_index_(1) { : next_index_(0)
is_valid_.reserve(n); {
is_valid_.reserve(initial_capacity);
} }
void Generate(size_t n, IndexType* indices) { void Generate(size_t n, IndexType* indices) {
if (n <= 0) { if (n == 0) return;
return;
}
size_t count_from_freed = std::min(n, freed_indices_.size()); size_t from_freed = std::min(n, freed_indices_.size());
for (size_t i = 0; i < count_from_freed; ++i) { for (size_t i = 0; i < from_freed; ++i) {
indices[i] = freed_indices_.back(); indices[i] = freed_indices_.back();
freed_indices_.pop_back(); freed_indices_.pop_back();
if (indices[i] >= is_valid_.size()) { is_valid_[indices[i]] = 1;
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false);
}
is_valid_[indices[i]] = true;
} }
for (size_t i = count_from_freed; i < n; ++i) { size_t need_new = n - from_freed;
indices[i] = next_index_++; if (need_new > 0) {
if (indices[i] >= is_valid_.size()) { size_t required = next_index_ + need_new;
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false); if (required > is_valid_.size()) {
size_t new_cap = std::max(required, is_valid_.size() * 2);
is_valid_.resize(new_cap, 0);
}
for (size_t i = 0; i < need_new; ++i) {
indices[from_freed + i] = next_index_;
is_valid_[next_index_] = 1;
++next_index_;
} }
is_valid_[indices[i]] = true;
} }
} }
void Delete(IndexType index) { void Delete(IndexType index) {
if (index < is_valid_.size() && is_valid_[index] == true) { if (index < is_valid_.size() && is_valid_[index]) {
is_valid_[index] = false; is_valid_[index] = 0;
freed_indices_.push_back(index); freed_indices_.push_back(index);
} }
} }
bool IsValid(IndexType index) const { bool IsValid(IndexType index) const {
return index < is_valid_.size() && is_valid_[index] == true; return index < is_valid_.size() && is_valid_[index];
} }
private: private:
IndexType next_index_; IndexType next_index_ = 0;
std::vector<IndexType> freed_indices_; std::vector<IndexType> freed_indices_;
std::vector<bool> is_valid_; std::vector<UInt8> is_valid_;
}; };
} }