STL只是个玩具,适用在小项目,高层应用上;大项目,底层,千万慎用,不小心就会给效率埋下无底大坑;
事情源起:近两天改写自己的引擎时,OXEntity类改用了两个新的数据结构map<int, map<int, OXTexture>, map<int, OXMesh>, 相关改动很多,主要是查找与设置,
程序编译运行后,吓了一跳,屏幕FPS由之前的130降到37,且启动时地形创建其慢无比,原来瞬间就可以创建的。
第一感觉,可能是STL的问题。查找所有改动的关于STL的代码。发现了许多弱智的用法。如下:
1 if(m_mmapTex[iMesh][iTex]&& !strcmp(m_mmapTex[iMesh][iTex]->GetResource(), pTex))return false;
2 if(m_mmapTex[iMesh][iTex])xresMgr.GetLoaderThread()->RemoveFromTexQueue(m_mmapTex[iMesh][iTex].GetPtr());
3 m_mmapTex[iMesh][iTex]= xresMgr.GetTex(pTex);
4 if(!m_mmapTex[iMesh][iTex])m_mmapTex[iMesh][iTex]= xresMgr.AddTex(pTex);
5 if(m_mmapTex[iMesh][iTex]->IsEmpty())xresMgr.GetLoaderThread()->Push2TexQueue(m_mmapTex[iMesh][iTex].GetPtr());
要知道,每个[]都会导致一次map.find(), 上面的用法多么可怕,底层代码的低效会在高层数十倍百倍的表现放大,这很可怕。修改后如下:
1 bool CXEntity::SetTexture(int iMesh, int iTex, cchar* pTex)
2 {
4 OXTexture& rOTex = m_mmapTex[iMesh][iTex];
5 if(rOTex && !strcmp(rOTex->GetResource(), pTex))return false;
6 if(rOTex)xresMgr.GetLoaderThread()->RemoveFromTexQueue(rOTex.GetPtr());
7 rOTex = xresMgr.GetTex(pTex);
8 if(!rOTex)rOTex = xresMgr.AddTex(pTex);
9 if(rOTex->IsEmpty())xresMgr.GetLoaderThread()->Push2TexQueue(rOTex.GetPtr());
10
11 return true;
12 }
可见STL有很多效率问题,在底层千万慎用,即使在高层,也不可大意,对于其内部原理要了解清楚。
一天后......
经过思索再三,最终决定基本放弃STL,尽可能少的使用。经过将几处大的STL改掉后,效率极大提高,看来它的效率差的不是一点半点.