Hi, I've been having performance issues with osg::Group, related to removing children one at a time. In one case, we have a group node with ~120,000 children, of which 30,000 need to be removed. This is much slower than expected - I'm consistently timing the removal at about 188 seconds total on my quad-core machine. About 187.99 of these seconds are spend on group.cpp line 182, which calls std::vector::erase:
_children.erase(_children.begin()+pos,_children.begin()+endOfRemoveRange);
The problem with this usage of erase is that everything after the last
erased element in the vector will be copied up, which in my case is a whole
lot of copies. One solution, which I'm now using, is to avoid calling erase
by making sure elements are only ever removed from the end of the vector.
Here's my replacement for the line above:
if (_children.size() == numChildrenToRemove)
{
_children.clear();
}
else
{
int numThingsToCopy = std::min(numChildrenToRemove,
_children.size() - numChildrenToRemove);
std::copy(_children.end() - numThingsToCopy, _children.end(),
_children.begin() + pos);
_children.resize(_children.size() - numChildrenToRemove);
}
With this change, removing the 30,000 nodes takes less than 1 second. It
does change the semantics of removing children from a group, in that the
children will be in a different order rather than just having their index
changed. In my opinion it's worth it for the performance gain.
The modified Group.cpp is attached.
-Max Bandazian
group.cpp
Description: Binary data
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
