問題描述
我認為通過引用傳遞應該比通過值傳遞更快,因為計算機不會復制數據,它只是指向數據的地址.
I thought that pass by reference should be faster then pass by value because the computer isn't copying data, it just points to the address of data.
但是,請考慮以下 C++ 代碼:
But, consider the following C++ code:
#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;
}
現在這段代碼只是一個普通的程序,它通過輸入三角形的所需行和位置來遞歸計算帕斯卡數.
Now this code is just a normal program that compute pascal number recursively by entering the desired row and position of the triangle.
我嘗試放置第 50 行和第 7 行,它計算大約 1 秒(按值傳遞).輸出大約是 1300 萬,這是正確的.所以我認為如果我通過引用傳遞它可能會更快,因為它不需要復制大量數據.但這是非常錯誤的,我不知道為什么需要更長的時間,大約是傳遞值所需的時間的 3 倍.問題是……
I tried putting row 50 and position 7 and it computes around 1 second (pass by value). The output is about 13 million which is correct. So I thought that it could be faster if I pass by reference instead because it doesn't need to copy a lot of data. But this is very wrong and I don't know why it took longer time about 3 times the amount it took for passing by value. The question is ...
為什么這個程序在我嘗試將其更改為通過常量引用后計算如此緩慢?
因為遞歸函數是一個例外,你應該通過值而不是常量引用傳遞,這有關系嗎?
Does it matter that because recursive function is an exception that you should pass by value rather than const reference?
推薦答案
哪個更快"的答案通常是這取決于".
The answer to "Which is faster" is usually "It depends".
如果不是傳遞 4 個字節的數據,而是傳遞一個指向數據的 8 個字節的指針,那么您真的不能指望這會讓事情變得更快.如果不是傳遞 100 個字節的數據,而是傳遞一個指向數據的 8 個字節的指針,那就不同了.
If instead of passing four bytes of data you are passing an eight byte pointer to data, then you can't really expect that to make things faster. If instead of passing 100 bytes of data you are passing an eight byte pointer to data, that's different.
但是現在函數沒有數據,它只有一個引用.所以每當它需要讀取數據時,它必須通過引用間接地做到這一點.那需要更長的時間.如果您傳遞一個 100 字節的對象并且只讀取其中的 8 個字節,您仍然有可能獲勝.但是,如果您實際上讀取了所有數據,并且可能多次讀取,那么即使對于大對象,傳遞值也很容易更快.
But now the function doesn't have the data, it only has a reference. So whenever it needs to read the data, it has to do that indirectly through the reference. That takes longer. If you pass a 100 byte object and only read eight byte of it, you still are likely to win. But if you actually read all the data, and maybe multiple times, then it could easily be faster to pass the value even for large objects.
真正的區別在于您傳遞對象時,而按值傳遞意味著將調用或多或少復雜的構造函數.通過引用傳遞意味著沒有構造函數.但是 int 無論如何都沒有構造函數.
The real difference comes when you pass an object, and passing by value means a more or less complex constructor will be called. Passing by reference means no constructor. But int has no constructor anyway.
然后是優化.按值傳遞意味著編譯器知道您的函數是唯一可以訪問數據的函數.通過引用傳遞意味著數據可以在任何地方.如果你有兩個 int&參數,我可以傳遞一些 int 兩次.所以增加行可能增加位置.或者它可能不會.這會扼殺優化.
And then there is optimisation. Passing by value means the compiler knows your function is the only one with access to the data. Pass by reference means the data could be anywhere. If you have two int& parameters, I could pass the some int twice. So increasing row might increase pos. Or it might not. That kills optimisations.
然后是優化規則:衡量它".你測量了它,發現什么更快.有時事情會無緣無故地更快或更慢.
And then there is the rule of optimisation: "Measure it". You measured it and found what's faster. Sometimes things are faster or slower for no good reason whatsoever.
這篇關于哪個更快?按引用傳遞與按值傳遞 C++的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!