Performance issue

rride

08-12-2010 15:19:54

We are using pagedgeometry to generate large arrays of trees. Our project is compiled under MSVS 2010 with CRT linked as multithreaded DLL.

The problems is that we are experiencing lags when a new grid cell is filled with trees. I've been investigating performance and found that half of time during which PG generates batches of trees it spends on string operations!!!!!!!!!

Look at the method!

String BatchedGeometry::getFormatString(SubEntity *ent)
{
StringUtil::StrStreamType str;

str << ent->getMaterialName() << "|";
str << ent->getSubMesh()->indexData->indexBuffer->getType() << "|";

const VertexDeclaration::VertexElementList &elemList = ent->getSubMesh()->vertexData->vertexDeclaration->getElements();
VertexDeclaration::VertexElementList::const_iterator i;
for (i = elemList.begin(); i != elemList.end(); ++i)
{
const VertexElement &element = *i;
str << element.getSource() << "|";
str << element.getSemantic() << "|";
str << element.getType() << "|";
}

return str.str();
}


AFAIN, MSVS implementation of STL uses locks in multithreaded version of CRT, so this method is extremely slow!

Look at the following profiling information:

Ogre::StrStreamType is used:
TreeLoader update 4.89 ms(avg)
TreeLoader update 5.53 ms(avg)

Ogre::StrStreamType is replaced with sprintf's:
TreeLoader update 2.49 ms(avg)
TreeLoader update 1.80 ms(avg)

So this code is almost twice as fast the previous one!

String BatchedGeometry::getFormatString(SubEntity *ent)
{
const int BufSize = 1024;
char buf[BufSize];


int countWritten =
_snprintf_s( buf, BufSize,
"%s|%d",
ent->getMaterialName().c_str(),
ent->getSubMesh()->indexData->indexBuffer->getType()
);

const VertexDeclaration::VertexElementList &elemList = ent->getSubMesh()->vertexData->vertexDeclaration->getElements();
VertexDeclaration::VertexElementList::const_iterator i;
for (i = elemList.begin(); i != elemList.end(); ++i)
{
const VertexElement &element = *i;
countWritten += _snprintf_s( buf + countWritten, BufSize - countWritten, BufSize - countWritten,
"|%d|%d|%d",
element.getSource(),
element.getSemantic(),
element.getType()
);
}

return buf;
}


I understand that Ogre has own coding conventions but sometimes performance is a little bit more important than coding conventions. :D

tdev

17-12-2010 13:12:53

indeed, very bad. i guess we should use global ids or such, patches and improvements welcome :)