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

Attachment: group.cpp
Description: Binary data

_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to