使用 C++11 的"自动"是否会降低性能甚至破坏代码?
Can the use of C++11's 'auto' deteriorate performance or even break the code?
这个问题与现有问题"使用C++11';s';auto';能提高性能吗?"相反
其中一个问题的答案表明,auto
的使用不仅有积极的影响,也有消极的影响。
我认为我们需要一个单独的问题,答案集中在auto
的那一边。
对于auto
,在变量声明+初始化行没有转换。但是,如果无论如何都必须进行这样的转换,那么在初始化期间最好进行一次,而不是以后多次。
struct X {
...
};
struct Y {
operator X() const;
...
};
Y foo(); // maybe, originally its return type was X but later was changed to Y
void bar(const X& );
const auto x = foo(); // <-- conversion not happening here
//
for ( int i = 0; i < 100; ++i ) //
bar(x); // <-- silently rages here
当auto
与懒惰评估相结合时,这种延迟转换可能会破坏代码(现实世界中的示例1、示例2):
class Matrix { ... };
class MatrixExpression {
...
operator Matrix() const;
};
MatrixExpression operator+(const Matrix& a, const Matrix& b);
std::ostream& operator(std::ostream& out, const Matrix& m);
Matrix a = ...;
Matrix b = ...;
auto c = a + b; // evaluation of the matrix addition doesn't happen here
a[0][0] += 1;
std::cout << c; // matrix addition is evaluated here, using the new state of 'a'
您的问题标题指定了"性能"。
auto
是一个编译时构造,它允许用推导的类型替换自己。它的使用不会产生不同的机器指令,就像你手写了它推导出的字体名称一样。
问题是,在管理性能时,类型规范和类型转换通常是至关重要的,而auto
可能会隐藏这一点,导致程序员说出与他们预期不同的东西:
std::vector<std::array<BigStruct, 10000>>& f();
auto va = f(); // copy
for (auto v: va) { // copies
// ...
}
如果程序员写过:
std::vector<std::array<BigStruct, 10000>> va = f();
或
for (std::array<BigStruct, 10000> v : va)
他们会意识到他们是通过价值来指定的。但std::array<BigStruct, 10000>
是auto
在这里推导的,在这些情况下,它可以通过值来转换。
人们放松了警惕,忘记了auto
推导出类型,它不包括裁判资格。
auto& va = f(); // reference
for (auto& v : va) { // references
这里有一个性能影响,但它不是由auto
引起的——它是(意外)显式指定副本的副作用。
auto
不是指the same as this
,而是指an instance of this
。
auto va = f(); // an instance-of what f returns, thus a copy.
auto& va = f(); // a reference to an instance-of, thus by reference.
无论何时使用支持初始化,auto对所有类型声明的盲搜索和替换都可能令人头疼:
class Point
{
public:
Point (int x1, int y1) { x = x1; y = y1; }
private:
int x, y;
};
int main()
{
Point p{5, 6};
auto q{5, 6}; // Error. Uniform initialization is not REALLY uniform
}
变量p的第一个声明被正确地推导为对接受两个整数的构造函数的调用。但是auto变量q搜索需要std::initializer_list <int
>的构造函数,因此无法编译。
相关文章:
- GCC 和 Clang 代码性能的巨大差异
- 如何使用本征提高性能?(包括示例代码)
- 在.cpp文件中定义方法而不是在 C++ 的 .h 文件中定义方法时,如何提高代码的性能?
- 使用 const double* const 作为模板参数 - 代码性能问题
- 如何在没有性能命中的情况下抽象SIMD代码来处理不同的数据类型
- 为什么 C++ 代码实现的性能不比 python 实现更好?
- 如何提高此 OpenCL 缩减内核代码的性能?
- 相同的代码在不同的 gcc 编译器中存在巨大的性能差异
- 如何基准C 代码的性能
- 相同的代码执行两次:性能差异
- 附加到 C++/CLI dll 的性能探查器无法访问本机C++代码
- 牢记干净的代码的性能,什么更好
- 在将其尺寸较大的向量移动到容量较小的向量之前,是否可以通过使用Reserve()来提高代码性能
- 如何提高四叉树代码的性能以防止程序冻结
- 从编译器优化和代码性能的角度来看,"if constexpr"与"if"
- 内存泄漏和代码性能
- C++代码性能字符串进行比较
- Dalvik 对原生 C++ 代码性能的影响?
- 为什么添加一条从未执行过的指令会导致我的代码性能下降
- 粒子模拟的并行化OpenMP代码性能差