C++ 循环中的奇怪 运行 次

Strange running times in C++ loops

所以,我正在编写一个程序,其中优化是一个关键因素。然而:在优化过程中,我注意到一个我认为相对简单的函数,花费的时间太长 运行。特别是相比之下,一个更困难的函数正在变得更短。

Whole Relevant section

// Simple function

int get_chunk_index(std::vector<Chunk> chunks, int x, int y) {
    glm::vec3 target = glm::vec3(x * 40, 0, y * 40);
    for (int i = 0; i < chunks.size(); i++) {
        if (chunks[i].trans.GetPos() == target) {
            return i;
        }
    }
    return -1;
}

// End simple function

如果您想要更多的功能,请随时询问,但它是一个相当大的程序,所以我不能在这里包含 所有内容

PS:chunks 的大小永远只有 0->40。

它最终只是简单的深拷贝,因为 Chunk 是一个很大的文件,我没有注意到副本。

工作代码:

// Simple function

int get_chunk_index(std::vector<Chunk>& chunks, int x, int y) {
    glm::vec3 target = glm::vec3(x * 40, 0, y * 40);
    for (int i = 0; i < chunks.size(); i++) {
        if (chunks[i].trans.GetPos() == target) {
            return i;
        }
    }
    return -1;
}

// End simple function

几个简单的选项。

1) chunks 正在按值传递,这会创建所传递向量的完整副本。尝试通过 const 引用(即 const std::vector<Chunk> &chunk)代替。

2) 与其传递 xy,并从中创建一个 glm::vec3(不管那是什么 - 它是非标准的),而是更改函数以接受 glm::vec3参考。这会强制调用者创建对象,但也允许调用者控制对象的更新(而不是每次都重新创建一个新对象)。

3) 将 chunks.size() 的计算从循环中取出,并使用预增量(不会创建临时)而不是 post-增量。

std::size_t size = chunks.size();
for (int i = 0; i < size; ++i) {
    if (chunks[i].trans.GetPos() == target)
    {
        return i;
    }
}

4) 考虑使用迭代器而不是数组索引。

std::vector<Chunk>::const_iterator i, begin = chunks.begin(), end = chunks.end();

for (i = begin; i != end; ++i)
   if (i->trans.GetPos() == target) return std::distance(begin, i);

或(C++11 及更高版本)

for (const auto &i : chunks)
{
    if (i.trans.GetPos() == target) return std::distance(chunks.begin(), i);
}

5) 不传递向量,而是传递其 beginend 迭代器。这样可以进一步简化循环。

6) 检查被调用的 getPos() 函数在做什么,并对其进行优化。

7) 在打开优化的情况下进行计时测量,并在函数的大量调用中进行测量。单个函数调用的性能测量在实践中意义不大(影响性能的其他因素的抖动将主导您的测量)。