3

假设从 std::vector 读取大量值的循环是我程序中的瓶颈,有人建议我改变

void f(std::vector<int> v)
{
    ...
    while (...)
    {
        ...
        int x = v[i] + v[j]
        ...
    }
}

void f(std::vector<int> v)
{
    int* p_v = &v[0];
    ...
    while (...)
    {
        ...
        int x = p_v[i] + p_v[j]
        ...
    }
}

通过绕过 [] 运算符,这实际上会提高性能吗?

4

5 回答 5

26

更有可能(从表面上看)每次调用此函数时复制整个向量是瓶颈。为什么不改为以下?

void f(const std::vector<int>& v)

在任何情况下,永远不要假设瓶颈在哪里——先测量,一旦确定就调整慢的代码。

于 2010-09-02T15:53:01.377 回答
15

不,这不应该影响性能。

请注意,在向量上使用传递引用到常量而不是传递值可能会更好。

编辑:有关其语法,请参阅@Steve Townsend 的答案。

于 2010-09-02T15:51:48.690 回答
4

不,不是物质上的。您以牺牲(可能)微不足道的性能收益为代价使代码更难阅读。无论如何,如果编译器没有operator[]在优化构建中内联调用,我会感到惊讶。

如果您不确定,请对其进行概要分析。我想它永远不会出现。

于 2010-09-02T15:51:04.360 回答
3

几乎所有有关性能的问题的标准答案是使用分析器来查看这是否是瓶颈并查看更改是否有帮助。但是,在这种情况下,我认为这不是一个特别好的建议。对于这样的代码,我已经查看了足够多的编译器的输出,我几乎可以说这是一个事实,即两者将生成相同的指令流。从理论上讲,这可能是错误的(虽然我使用过很多编译器,但肯定还有其他我没有使用过的编译器),但实际上,如果是这样,我会感到非常惊讶。虽然可能有一个或两个预先(循环外)不同的指令,但我希望循环中的内容是相同的。

于 2010-09-02T15:57:30.773 回答
0

如果您只需要顺序访问向量的内容(遗憾的是,您的示例显示看似随机访问,所以这不起作用,但也许这只是一个示例),您可以通过使用迭代器来显着提高速度遍历向量。我已经看到,即使在启用了完整编译器优化的普通数组上,这种优化也会产生显着差异。

于 2010-09-02T17:42:09.300 回答