为什么要存储引用而不是请求它两次我的应用程序这么慢?

Nik*_*iko 1 c++

对象memory具有带签名的方法

BinaryPattern const& getPattern(unsigned int index) const;
Run Code Online (Sandbox Code Playgroud)

我在下面的for循环中使用它:

for (unsigned int k = 0; k < memory->size(); k++) {
    const BinaryPattern s = memory->getPattern(k);
    w += s.at(i) * s.at(j);
}
Run Code Online (Sandbox Code Playgroud)

这很慢.令人惊讶的是,我发现以下内容要快得多:

for (unsigned int k = 0; k < memory->size(); k++) {
    w += memory->getPattern(k).at(i) * memory->getPattern(k).at(j);
}
Run Code Online (Sandbox Code Playgroud)

"getPattern()"不进行任何计算,它几乎只返回存储在向量中的模式.

当我将引用存储在变量中时,为什么这么慢?我最初这样做是为了加快速度,因为我预计两次检索引用会变慢.

sbi*_*sbi 9

这是因为

const BinaryPattern s = memory->getPattern(k);
Run Code Online (Sandbox Code Playgroud)

通过调用其复制构造函数来复制该对象.由于您不想更改它,请存储引用:

const BinaryPattern& s = memory->getPattern(k);
//                 ^
//                 note this
Run Code Online (Sandbox Code Playgroud)

(由于使用const引用捕获rvalue会延长rvalue的生命周期,直到引用消失为止,这甚至可以getPattern()在更改签名时返回副本而不是引用.)


在优化的构建中(您没有比较调试版本,是吗?),编译器可能能够确定对函数的两次调用

memory->getPattern(k).at(i) * memory->getPattern(k).at(j)
Run Code Online (Sandbox Code Playgroud)

没有任何副作用,因此保持对第一次调用获得的对象的引用并优化掉第二次调用 - 到达我上面提出的代码.

显然,复制BinaryPattern对象的成本是不容忽视的.

  • @Niko:代码中的变量`s`是一个对象,而不是一个引用.初始化的内容对此没有任何影响. (3认同)