我最近去了一个程序工作面试,他们让我写一些函数,它将一个矢量和一个整数作为参数。任务是计算向量中高于,低于或等于整数的元素数。我写了一些东西:
void printStat(const std::vector<int> &vec, const int &val)
{
int results[3] = {0,0,0};
for (int i = 0; i < vec.size(); ++i) {
int option = (vec[i] == val) ? 0 : ((vec[i] > val) ? 1 : 2);
results[option]++;
}
...
}
他们对我发现可疑的代码做了几点评论,我想知道C ++专家的意见。他们说通过引用传递vec
和val
的效率低于值。写下本来会更好:
void printStat(const std::vector<int> vec, const int val) {}
老实说,我总是使用第一个版本(在顶部)编写我的代码并且没有真正的论据来解释为什么我的方法会比他们的方法更好或没有区别。他们的论点是,当你想要它的内容时,通过引用传递参数会强制取消引用变量,这比我按值传递变量要慢。
所以我的问题是:什么是最好的方式,原因是什么?
奖金问题:他们还认为在循环中使用迭代器比使用[]
运算符访问向量元素更有效。我没有看到任何理由,特别是因为我怀疑在第5行访问两次时vec[i]
将在L1缓存中。
谢谢。
答案 0 :(得分:4)
这取决于您将如何使用vec
。如果您在向量中没有很多条目,则可以通过值传递它,因为复制将非常快。但一般来说,通过引用传递它会更“有效”。
另一方面,val
参数,对于本机类型,通常不需要将它们作为常量引用传递。实际上,由于引用通常(如果不总是?)实现为引擎盖下的引用,将此参数作为引用传递将在64位机器上传递64位值,而不是32位值为plain {{1 }}。因为这是一个指针,它也会使用额外的间接。
答案 1 :(得分:1)
通过ref传递内置类型的对象会导致额外的负载。只要使用const int val,如果你想阻止它修改。使用std :: vector by ref似乎绝对有效。
答案 2 :(得分:1)
我会坚持通过const引用传递对象。一个例外是,无论如何都要复制(const T没有意义,除了防止函数实现中的意外更改)。
但是:我改变了实施operator =
的方式。
T& operator=(const T& other) {
T(other).swap(*this);
return *this;
}
到
T& operator=(T other) {
other.swap(*this);
return *this;
}
允许复制省略和移动语义。