【发布时间】:2023-03-19 18:01:03
【问题描述】:
我编写了一个波前 Obj 解析器类,用于将 obj 模型导入我的 OpenGL 项目。我在调试模式下测试了这个类,发现它慢得让人难以忍受。
代码有效,我做了明显的调整,以确保它在合理实用的范围内尽可能高效。
不过,加载我的测试文件,一个 12mb 的 obj 文件,运行大约 330,000 行文本,需要一分钟多的时间来解析。
很沮丧,我有一个谷歌,果然,I wasn't the first person to run into this problem。
这个在 gamedev.net 上发布查询的人只是在发布模式下运行他的算法,在 Visual Studio IDE 和 whammo 之外运行,性能可以接受。这也对我有用,我的 ~70 秒减少到 ~3 秒。
我对算法进行了一些分析,瓶颈在于对 std::getline 的调用,以及以下内容:
sstream >> sToken;
其中 sstream 是一个 std::stringstream 而 sToken 是一个 std::string(预先保留空间)。
问题
为什么 IDE 在运行我的解析算法时速度如此之慢(即使在发布模式下) - 在通过 IDE 运行代码时我可以做些什么来加快这一速度(F5 - 运行项目)?这使得调试变得非常缓慢。 IDE 是否将代码/挂钩注入到可执行文件中以通过 IDE 运行,或者这是否可以归结为缓存未命中或其他原因?
优化
我对文件进行两次遍历,在遍历一次时,我只计算令牌类型 - 这样我就可以保留空间(而不是迭代增长存储顶点、法线、texcoords、面等的向量)
sLineBuffer.reserve( 100 );
sToken.reserve(10);
while( sstream.good() )
{
sstream >> sToken;
getline( sstream, sLineBuffer );
if( sToken.compare("f") == 0 )
nFaces ++;
else if( sToken.compare("v") == 0 )
nVertices ++;
else if( sToken.compare("vn") == 0 )
nNormals ++;
else if( sToken.compare("vt") == 0 )
nTextures ++;
else if( sToken.compare("g") == 0 )
nGroups ++;
}
m_Vertices.reserve( nVertices );
m_Normals.reserve( nNormals );
m_TexCoords.reserve( nTextures );
m_Faces.reserve( nFaces );
m_Groups.reserve( nGroups );
第一次通过的成本很低(在调试模式下约为 8 秒,在 IDE 外的发布模式下约为 0.3 秒),并且效率节省很大(将解析时间从调试模式下的约 180 秒减少到约 60 秒)。
我还将整个文件读入一个字符串流中,以便将磁盘访问排除在等式之外:
// Read entire file from disk into memory
fstream stream;
stringstream sstream;
stream.open( m_sFilename.c_str(), std::ios::in );
sstream << stream.rdbuf();
stream.close();
此外,在可能的情况下,在整个算法中,我会尝试提前为 std::strings 预留空间,以便它们不会根据每个字符调整大小:
sLineBuffer.reserve( 100 );
sToken.reserve(10); // etc
【问题讨论】:
-
也许映射文件会有所帮助。
-
“在 IDE 中运行”是指在调试器下运行,还是用 Ctrl-F5 启动也有同样的问题?此外,当您在 IDE 之外运行时,您使用的是相同的二进制文件还是不同的版本,即使两者都是“发布”版本,编译器选项也可能存在一些差异?
-
这可能与您报告的减速无关,但代码
while(sstream.good())不是一个好主意。以这种方式测试.good()或.eof()的I/O 循环是bad practice。 -
当然慢,是debug构建。在调试版本中转储一个大数据集,用一个小数据集测试它,依靠发布版本来处理一个大数据集是没有意义的。
-
Blastfurnace - .good() 不会成为使用 Glowcode 分析算法的瓶颈。你能解释一下为什么你认为这是一个坏主意吗?哦,刚刚找到你的链接,没关系
标签: c++ visual-studio-2010 optimization