因爲在現代硬件上製作原始單個拷貝的代價非常低,所以您顯示的代碼示例是微型優化(或者微型優化,無論情況如何)。對基元進行引用也是一樣的。與調用任何感興趣的函數的成本相比,成本會降低。
但是,對示例的一個非常簡單的更改演示了在對基元的引用變得有益時的情況,因爲您可以將它們分配回去。
這裏就是你們的榜樣修改的地方使用std::map<std::string,int>
的std::vector<int>
:
std::map<std::string,int> cache;
int compute_new(int old) {
return old+1;
}
void fun_with_ref(const std::string& key) {
int& int_ref = cache[key];
int_ref = compute_new(int_ref);
}
void fun_with_val(const std::string& key) {
int int_val = cache[key];
cache[key] = compute_new(int_val);
}
注意如何fun_with_ref
執行由key
單個查找,而fun_with_val
需要兩個查找。 std::map<std::string,ing>
的訪問時間增長爲O(日誌 N),因此當地圖增長到較大時節省可能變得很重要。
A quick micro-benchmark顯示使用具有1,000,000個條目的映射的引用的代碼幾乎是使用值的代碼的兩倍。
vector<string> keys;
for (int i = 0 ; i != 1000000 ; i++) {
auto key = to_string(i);
cache[key] = i;
keys.push_back(key);
}
auto ms1 = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
).count();
for (const string& key : keys) {
fun_with_ref(key);
}
auto ms2 = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
).count();
for (const string& key : keys) {
fun_with_val(key);
}
auto ms3 = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
).count();
cout << "Ref: " << (ms2-ms1) << endl;
cout << "Val: " << (ms3-ms2) << endl;
輸出:
Ref: 557
Val: 1064
你可以看一下彙編代碼。編譯器可能會刪除所有內容。 – juanchopanza
爲什麼首先需要對變量進行額外引用?你可以寫'int_fun(test [0])'。 – user463035818
@ tobi303你是對的,它只是爲了清晰起見 - 有時函數需要大量參數,每個參數的形式都是var.GetAnotherVar()。GetSomethingElse()。value(),所以它更容易分解很少 - 也許這只是個人喜好。 –