文件加载太慢!(c++)

File loading too slow! (C++)

本文关键字:c++ 加载 文件      更新时间:2023-10-16

我正在尝试为DirectX引擎编写一个模型文件加载器…

现在看起来是这样的:

irrFireMesh* irrFireDevice::loadModel(char* filename)
{
ifstream in_stream;
string line;
in_stream.open(filename);
int vertexCount = 0;
int vCount = -1;
irrFireMesh* triangleMesh = new irrFireMesh();
irrFireVertex* vertices;
unsigned long* indices;
irrFireMaterial* mat;
while(getline(in_stream, line, 'n'))
{
    std::string word;
    std::stringstream stream(line);
    std::string param[15];
    int i = 0;
    while( getline(stream, word, ' ') ){
    param[i] = word;
    i++;
    }
    then = timeGetTime();
    if(param[0] == "newbuf")
    {
        vertexCount = StI(param[1]);
        vertices = new irrFireVertex[vertexCount];
        if(!vertices) return NULL;
        indices = new unsigned long[vertexCount];
        if(!indices) return NULL;
        mat = new irrFireMaterial(this);
        cout<<"Begin buffer width "<<vertexCount<<" vertices"<<endl;
        vCount = -1;
        continue;
    }
    if(vertexCount <= 0) continue;
    if(param[0] == "endbuf")
    {
        irrFireMeshBuffer* mbuf = new irrFireMeshBuffer();
        mbuf->vertexCount = vertexCount;
        mbuf->indexCount = vertexCount;
        mbuf->vertices = vertices;
        mbuf->indices = indices;
        mat->INITIALIZE();
        mbuf->material = mat;
        triangleMesh->addMeshBuffer(mbuf);
        vertexCount = 0;
        cout<<"End buffer width "<<vCount+1<<" vertices."<<endl;
        continue;
    }
    if(param[0] == "v")
    {
        vCount++;
        vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));
        vertices[vCount].color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
        vertices[vCount].uv = D3DXVECTOR2((StF(param[1]) + StF(param[3]))*10.0f, StF(param[2])*10.0f);
        indices[vCount] = vCount;
        if((vCount+1) % 3 == 0)
        {
            D3DXVECTOR3 NRML, D1, D2;
            D1 = vertices[vCount-2].position - vertices[vCount-1].position;
            D2 = vertices[vCount-1].position - vertices[vCount].position;
            D3DXVec3Cross(&NRML, &D1, &D2);
            D3DXVec3Normalize(&NRML, &NRML);
            vertices[vCount-2].normal = NRML;
            vertices[vCount-1].normal = NRML;
            vertices[vCount].normal = NRML;
        }
        continue;
    }
}
in_stream.close();
return triangleMesh;
}

一个三角形的模型文件看起来像这样:

newbuf 3
v 0.0 0.0 0.0
v 0.5 1.0 0.0
v 1.0 0.0 0.0
endbuf

它的工作方式就像它应该,但方式太慢,当加载复杂的模型…你能给我指出瓶颈并指出更快的解决方法吗?

编辑:我对一些函数所需的时间进行了基准测试结果显示,解析部分

if(param[0] == "v")
{
.
.
.
}
在解析23400个顶点时,

总共花费大约4000 ms。但是当我替换

vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));

vertices[vCount].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

总共只需要大约300毫秒。所以性能杀手似乎是StF(),它看起来像这样:

float StF(string in)
{
stringstream mystr("");
mystr<<in;
float res = 0;
mystr>>res;
return res;
}

有什么好主意吗?

"new"命令的开销取决于遇到多少"newbuf"节,但在我看来,您需要新命令,因为您需要保存每个数组。转换为矢量可能不是一个选项,这取决于你是否可以修改网格类。

如果您有访问分析器的权限,那么可以使用它来验证它在哪里花费了时间。它可以告诉您哪些代码行比其他代码行更糟糕。很多时候,这应该是你尝试优化的第一步;通常,如果你只是试着看它,你最终会猜错。

以文本格式阅读会比较慢。此外,从字符串到浮点数的转换需要一些时间,以及新的命令。您可能可以将每个"newbuf"部分作为字符串数组读入,并将处理多线程化(其中new和其他处理并行处理)。在将数组添加回目标网格之前,您必须同步内容。