因为在现代硬件上制作原始单个拷贝的代价非常低,所以您显示的代码示例是微型优化(或者微型优化,无论情况如何)。对基元进行引用也是一样的。与调用任何感兴趣的函数的成本相比,成本会降低。
但是,对示例的一个非常简单的更改演示了在对基元的引用变得有益时的情况,因为您可以将它们分配回去。
这里就是你们的榜样修改的地方使用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(),所以它更容易分解很少 - 也许这只是个人喜好。 –