gpt4 book ai didi

c++ - 带有 getline 的慢 istringstream

转载 作者:行者123 更新时间:2023-11-30 01:23:55 25 4
gpt4 key购买 nike

我有一个 Wavefront .obj 文件解析器,它使用 getline 和 stringstream 解析数据。起初当模型很小的时候,没有问题,但是现在,当我尝试加载一个有 ~207000 行的模型时,只有在我计算所有元素的第一次通过时,它花费了荒谬的时间(~4.7s)在高结束 PC,第二遍需要半分钟。另一方面,Blender 仅需 2 秒左右即可加载整个模型。我使用的是 visual studio 2012,目前处于 Debug模式。

我计算元素的代码如下所示:

istringstream input(obj);
string line;
while (getline(input, line)) {
if (line.find("# ") != string::npos) {
// Comments.
}
else if (line.find("f ") != string::npos) {
faces++;
}
else if (line.find("v ") != string::npos) {
vertices += 3;
}
else if (line.find("vn ") != string::npos) {
normals += 3;
}
else if (line.find("vt ") != string::npos) {
uvCoordinates += 2;
}
else if (line.find("o ") != string::npos) {
// Count here, if needed.
}
}

实际加载整个数据的代码大约需要 30 秒:

istringstream input(obj);
string line;
if (faces.capacity() > UINT_MAX / 3) {
LOGE("Model cannot have more faces than: %d", UINT_MAX / 3);
return false;
}
while (getline(input, line)) {
vector<string> arr = stringSplit(line, ' ');
string param = arr[0];
int params = arr.size();
if (line.length() == 0) {
continue;
}

if (arr[0] == "v") { // Vertices.
vertices.push_back(stringToFloat(arr[1].c_str()));
vertices.push_back(stringToFloat(arr[2].c_str()));
vertices.push_back(stringToFloat(arr[3].c_str()));
}
else if (arr[0] == "vn") { // Normals.
normals.push_back(stringToFloat(arr[1].c_str()));
normals.push_back(stringToFloat(arr[2].c_str()));
normals.push_back(stringToFloat(arr[3].c_str()));
}
else if (arr[0] == "f") { // Faces.
if (params < 4) {
//LOGI("LINE: %s", line.c_str());
continue;
}
else if (params > 4) {
LOGI("Line: %s", line.c_str());
LOGE("Obj models must only contain triangulated faces.");
return false;
}
Face face;
parseFace(face, line);
faces.push_back(face);
}
else if (arr[0] == "vt") { // UV coordinates.
uvCoordinates.push_back(stringToFloat(arr[1].c_str()));
uvCoordinates.push_back(stringToFloat(arr[2].c_str()));
}
else if (arr[0] == "mtllib") { // Material.
material = arr[1];
}
else if (arr[0] == "o") { // Sub-model.
// Separate models here, if needed.
}
}

obj 变量是一个包含整个文件内容的字符串。从第一个循环内部删除所有内容对时间影响没有任何影响。关于如何优化这个的任何想法?

最佳答案

首先,尝试发布版本。调试构建意味着可调试,而不是快速。

另一件事是使用 stringstream 和 getline 会导致大量复制和堆分配。为了获得最佳性能,您可以尝试仅使用索引遍历字符串,从原始字符串本身而不是提取的片段中解析内容,等等。当然,您需要替换标准库中的一些功能。

关于c++ - 带有 getline 的慢 istringstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14316264/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com