В моем пользовательском физическом движке самым большим узким местом является метод, который получает все тела из пространственного разбиения (2D-сетку) и возвращает коллекцию, содержащую только уникальные указатели на тело.
template<typename T, typename V> bool contains(const T& mContainer, const V& mValue)
{
return std::find(std::begin(mContainer),
std::end(mContainer), mValue) != std::end(mContainer);
}
const vector<Body*>& GridInfo::getBodiesToCheck()
{
bodiesToCheck.clear();
for(auto& query : queries)
for(auto& body : *query)
if(!contains(bodiesToCheck, body)) bodiesToCheck.push_back(body);
return bodiesToCheck;
}
Использование профилировщика показывает, что узкое место находится в методе "содержит".
Очевидно, что a std::unordered_set
будет "идеальным" решением. Однако это намного медленнее, чем текущее решение. Я также пробовал google::dense_hash_set
, который быстрее, чем std::unordered_set
, но все же медленнее, чем текущее решение.
const unordered_set<Body*>& GridInfo::getBodiesToCheck()
{
bodiesToCheck.clear();
for(auto& query : queries)
for(auto& body : *query)
/*if(!contains(bodiesToCheck, body))*/ bodiesToCheck.insert(body);
return bodiesToCheck;
}
Почему "правильные" контейнеры медленнее, чем std::vector
?
Есть ли способ ускорить этот метод?