c++ - Using std::remove_if with lambda predicate to delete multiple elements -


what fastest , efficient way of using std::remove_if lambda predicate delete multiple elements @ same time? @ moment have point struct position , unique id. inside update loop fill points vector , add points deleted @ end of update loop. @ moment have call remove_if inside loop remove deleted points points vector. example if add 10 points per frame , after loop points check if point outside screen bounds, if added deletedpoints_.

struct point {     /// position.     vector3 position_;     /// unique id per point     int id_; }  /// current max id int maxid_;  /// points std::vector<point> points_; /// deleted points std::vector<point> deletedpoints_;   //updates 60fps void app::update() {     /// add 10 points per frame     (int = 0; < 10; ++i)     {         point newpoint;         /// add position         newpoint.position_ = worldposition;         /// add id starts 1         maxid_ += 1;         startpoint.id_ = maxid_;         /// add new point in points         points_.push(newpoint);     }      /// if points outside of screen bounds add them deletedpoints_     if (points_.size() > 0)     {         (int = 0; < points_.size(); ++i)         {             /// bounds             vector2 min = vector2(0.00,0.00);             vector2 max = vector2(1.00,1.00);             /// check bounds              if(points_[i].x < min.x || points_[i].y < min.y || points_[i].x > max.x || points_[i].y > max.y)             {                    deletedpoints_.push(points_[i]);             }          }          /// loop deleted points         (int = 0; < deletedpoints_.size(); ++i)         {             int id = deletedpoints_[i].id_;             /// remove id             auto removeit = std::remove_if(points_.begin(), points_.end(),                                   [id](const trailpoint2& point)                                   { return point.id_ == id; });             points_.erase(removeit, points_.end());         }     }    } 

without changing structures, quickest fix invert whole loop , check deletedpoints inside lambda instead.

then, make deletedpoints std::set<int> storing unique ids. it'll relatively fast, because std::set<int>::find doesn't need scan entire container, though final complexity still not quite linear-time.

std::vector<point> points_; std::set<int> deletedpointids_;  /// remove id auto removeit = std::remove_if(points_.begin(), points_.end(),                       [&](const trailpoint2& point)                       { return deletedpointids_.count(point.id_); }); points_.erase(removeit, points_.end()); deletedpointids_.clear(); 

that being said, whether switch on std::set actually faster depends on few things; lose memory locality , drop cache opportunities due way in set's elements stored.

an alternative might keep vector (of ids not points!), pre-sort it, use std::binary_search benefits of quick search benefits of sequentially-stored data. however, performing search may not suitable application, depending on how data have , on how need execute algorithm.

you use std::unordered_set<int> instead of std::set; has same problems std::set hash-based lookup may faster tree-based lookup. again, entirely depends on size, form , distribution of data.

ultimately, way know sure, try few things @ simulated extents , measure it.


Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -