C++ 为什么std::vector比数组指针慢得多

C++ 为什么std::vector比数组指针慢得多,c++,opengl,C++,Opengl,我正在创建一个Opengl字体批处理绘图 我想知道为什么我的std::vector比使用数组指针慢得多 我已经尝试添加向量保留和我能想到的一切 当使用向量时,我的FPS下降了一半以上 向量看起来更容易管理,代码看起来也更漂亮,但我真的很坚持这一点 不确定我是否错过了一些简单的东西 还是只使用数组指针更好 #ifdef USE_VECTORS std::vector<Vertex> m_vertices; #else Vertex *m_pVertex; Ver

我正在创建一个Opengl字体批处理绘图

我想知道为什么我的std::vector比使用数组指针慢得多

我已经尝试添加向量保留和我能想到的一切

当使用向量时,我的FPS下降了一半以上

向量看起来更容易管理,代码看起来也更漂亮,但我真的很坚持这一点

不确定我是否错过了一些简单的东西

还是只使用数组指针更好

#ifdef USE_VECTORS
    std::vector<Vertex> m_vertices;
#else
    Vertex *m_pVertex;
    Vertex m_vertices[MAX_VERTICES];
#endif

你把苹果和桔子做比较:

容器本身包含指针,减少了数据的局部性。 更改大小时,容器需要重新分配存储。 Microsoft的Visual Studio在其标准库容器中启用了其他诊断功能。例如,如果索引超出范围,则通过vec[123]访问会导致每个标准的未定义行为。这允许通过指向数组有效负载的指针实现简单的索引。通过额外的诊断,可以验证索引,这只是一个小的比较和一个分支,但在紧密的循环中,它会产生不同。
也就是说,你证明某些东西的方法是有缺陷的。您首先必须按照MCVE的精神实现尽可能减少的等效代码。将OpenGL后端挂接到它上不会使事情重复。

您看到性能差异很大的主要原因是调试模式

在调试模式下,默认情况下MSVC不内联任何内容,不在寄存器中存储任何变量,并且始终分配和验证堆栈帧,没有名字


在调试模式下使用向量时,额外的抽象将直接转化为CPU的更多工作。

启用了优化?是否在发布模式下构建=启用了优化?您使用的编译器是什么?我只是在visual studio 2015中以调试模式进行测试。这是不公平的比较,您应该尝试std::array而不是debug timings大致基准测试我使用了多少抽象,而不是实际代码的速度
    void GLFont::drawChar(char c, int x, int y)
    {
        //  1------4
        //  |      |            1 = (x, y)
        //  |      |            2 = (x, y + charHeight)
        //  |      |            3 = (x + charWidth, y + charHeight)
        //  |      |            4 = (x + charWidth, y)
        //  |      |
        //  |      |
        //  2------3
        //

        const Glyph &glyph = getChar(c);
        int charWidth = glyph.width;
        int charHeight = m_charHeight;

    #ifdef USE_VECTORS
        Vertex vert[] = {
            x, y,
            glyph.upperLeft[0], glyph.upperLeft[1],
            m_color[0], m_color[1], m_color[2], m_color[3],

            x, y + charHeight,
            glyph.lowerLeft[0], glyph.lowerLeft[1],
            m_color[0], m_color[1], m_color[2], m_color[3],

            x + charWidth, y + charHeight,
            glyph.lowerRight[0], glyph.lowerRight[1],
            m_color[0], m_color[1], m_color[2], m_color[3],

            x + charWidth, y,
            glyph.upperRight[0], glyph.upperRight[1],
            m_color[0], m_color[1], m_color[2], m_color[3]
        };
        //unsigned dataArraySize = sizeof(vert) / sizeof(Vertex);

        m_vertices.insert(m_vertices.end(), &vert[0], &vert[4]);

        ++m_numCharsToDraw;
    #else
         //1
        m_pVertex->x = x;
        m_pVertex->y = y;
        m_pVertex->s = glyph.upperLeft[0];
        m_pVertex->t = glyph.upperLeft[1];
        m_pVertex->r = m_color[0];
        m_pVertex->g = m_color[1];
        m_pVertex->b = m_color[2];
        m_pVertex->a = m_color[3];
        ++m_pVertex;

        // 2
        m_pVertex->x = x;
        m_pVertex->y = y + charHeight;
        m_pVertex->s = glyph.lowerLeft[0];
        m_pVertex->t = glyph.lowerLeft[1];
        m_pVertex->r = m_color[0];
        m_pVertex->g = m_color[1];
        m_pVertex->b = m_color[2];
        m_pVertex->a = m_color[3];
        ++m_pVertex;

        // 3
        m_pVertex->x = x + charWidth;
        m_pVertex->y = y + charHeight;
        m_pVertex->s = glyph.lowerRight[0];
        m_pVertex->t = glyph.lowerRight[1];
        m_pVertex->r = m_color[0];
        m_pVertex->g = m_color[1];
        m_pVertex->b = m_color[2];
        m_pVertex->a = m_color[3];
        ++m_pVertex;

        // 4
        m_pVertex->x = x + charWidth;
        m_pVertex->y = y;
        m_pVertex->s = glyph.upperRight[0];
        m_pVertex->t = glyph.upperRight[1];
        m_pVertex->r = m_color[0];
        m_pVertex->g = m_color[1];
        m_pVertex->b = m_color[2];
        m_pVertex->a = m_color[3];
        ++m_pVertex;

        if (++m_numCharsToDraw == MAX_CHARS_PER_BATCH)
        {
            drawTextEnd();
            drawBatchOfChars();
            drawTextBegin();
        }
    #endif
    }

void GLFont::drawBatchOfChars()
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

#ifdef USE_VECTORS
    glVertexPointer(2, GL_INT, sizeof(Vertex), &m_vertices[0].x);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &m_vertices[0].s);
    glColorPointer(4, GL_FLOAT, sizeof(Vertex), &m_vertices[0].r);
#else
    glVertexPointer(2, GL_INT, sizeof(Vertex), &m_vertices->x);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &m_vertices->s);
    glColorPointer(4, GL_FLOAT, sizeof(Vertex), &m_vertices->r);
#endif

    glDrawArrays(GL_QUADS, 0, m_numCharsToDraw * 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}