哪个更快?通过引用传递vs传递值C++

off*_*555 0 c++ recursion pass-by-reference pass-by-value pass-by-const-reference

我认为通过引用传递应该更快然后传递值,因为计算机不是复制数据,它只是指向数据的地址.

但是,请考虑以下C++代码:

#include <iostream>
#include <cassert>
#include <cmath>

using namespace std;

// do not use pass by reference& with this function, it will become so slow
unsigned long long computePascal(const unsigned int row, const unsigned int position) {
    if (position == 1 || position == row)
    return 1L;
    unsigned long long left = computePascal(row-1, position-1);
    unsigned long long right = computePascal(row-1, position);
    unsigned long long sum = left + right;
    return sum;
}

int main() {
    int row, position;
    cout << "Input row and position: ";
    cin >> row >> position;
    assert(position > 0 && position <= row);
    unsigned long long pascalNumber = computePascal(row, position);
    cout << pascalNumber << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在这段代码只是一个普通的程序,通过输入三角形所需的行和位置来递归地计算pascal数.

我尝试将第50行放在第7位并计算大约1秒(按值传递).输出大约是1300万,这是正确的.所以我认为如果我通过引用传递它可能会更快,因为它不需要复制大量数据.但这是非常错误的,我不知道为什么花费更长的时间大约是通过价值所需金额的3倍.问题是 ...

在我尝试将其更改为通过const引用传递之后,为什么此程序计算得如此之慢?

这是否重要,因为递归函数是一个异常,您应该通过值而不是const引用传递?

gna*_*729 8

"哪个更快"的答案通常是"它取决于".

如果不是传递四个字节的数据而是传递一个8字节的数据指针,那么你真的不能指望它能让事情变得更快.如果不是传递100个字节的数据,而是传递一个8字节的数据指针,那就不同了.

但是现在函数没有数据,它只有一个参考.因此,只要需要读取数据,它就必须通过引用间接地做到这一点.这需要更长时间.如果你传递一个100字节的对象并且只读取它的八个字节,你仍然可能获胜.但是如果您实际读取了所有数据,并且可能多次读取数据,那么即使对于大型对象,也可以更快地传递该值.

传递一个对象时会产生真正的差异,并且通过值传递意味着将调用一个或多或少复杂的构造函数.通过引用传递意味着没有构造函数.但是int无论如何都没有构造函数.

然后是优化.按值传递意味着编译器知道您的函数是唯一可以访问数据的函数.通过引用传递意味着数据可以在任何地方.如果你有两个int和参数,我可以传递一些int两次.因此增加行可能会增加pos.或者它可能不会.这会导致优化失败.

然后是优化规则:"测量它".你测量了它,发现了什么更快.有时事情会更快或更慢,没有任何理由.