我已经尽力找到这个问题的答案,但运气不佳。此外,我已经对其进行了测试,并且在优化的发布版本中没有发现任何差异(调试存在差异)......仍然,我无法想象为什么没有差异,或者优化器如何能够取消惩罚,也许有人知道内部发生了什么。
如果我在循环中创建一个简单类/结构的新实例,在每次循环迭代中创建类/结构的效率是否会有任何损失?
即
struct mystruct
{
inline mystruct(const double &initial) : _myvalue(initial) {}
double myvalue;
}
为什么...
for(int i=0; i<big_int; ++i)
{
mystruct a = mystruct(1.1)
}
花费与实际时间相同的时间
for(int i=0; i<big_int; ++i)
{
double s = 1.1
}
??构造函数/初始化不需要一些时间吗?
最佳答案
对于现代优化器来说,这是一项轻松的工作。
作为一名程序员,您可能会在查看构造函数和结构时认为它必须付出一些代价。 “构造函数代码涉及分支、通过寄存器/堆栈传递参数、从堆栈弹出等。结构是用户定义的类型,它必须在某处添加更多数据。const 引用存在别名/间接开销,等等。”
除了优化器然后开始检查您的代码,它注意到 struct
没有虚函数,它没有需要非平凡构造函数的对象。整个事情都适合通用寄存器。然后它注意到您的构造函数只是将一个变量分配给另一个变量。它甚至可能会注意到你只是用一个文字常量调用它,它转换为一个单一的移动/存储指令到一个寄存器,除了指令之外甚至不需要任何额外的内存。
这一切都非常神奇,编译器是复杂的野兽,但它们通常会多次执行此操作,从原始代码到中间表示,再从中间表示到机器代码。要真正欣赏和理解他们的工作,不时看一下拆解是值得的。
值得注意的是,C++ 已经存在了几十年。作为 C 的后继者,它最初主要被推为一种面向对象的语言,具有封装和信息隐藏等热门概念。为了推广一种人们开始替换公共(public)数据成员和手动初始化/销毁以及类似简单访问函数、构造函数、析构函数的语言,如果即使是一个简单的函数也有可测量的开销,那么普及该语言将非常困难称呼。听起来很神奇,C++ 优化器几十年来一直在做这件事,压缩你添加的所有开销,使事情更容易维护到与不太容易维护的程序集相同的程序集。
因此,通常值得将函数调用和小型结构之类的事情视为基本上免费的,因为如果值得内联并将所有开销压缩到零,优化器通常会这样做。间接函数调用会出现异常:虚拟方法、通过函数指针进行的调用等。但是您发布的代码很容易被现代优化器压缩。
关于c++ - 在循环中初始化结构/类的效率损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30722351/