wro*_*ame 21 c++ int optimization class
如果我有一个如此定义的类:
class classWithInt
{
public:
classWithInt();
...
private:
int someInt;
...
}
Run Code Online (Sandbox Code Playgroud)
那someInt
是一个且只有一个成员变量classWithInt
,它慢多少.将宣布这个类,而不是只需要声明一个新的整数的新实例?
你有什么时候,在课堂上说10个这样的整数?100?
Kar*_*tel 43
由于编译器不是在凌晨时分醉酒的大学生写的,开销是零.至少在你开始投入virtual
功能之前; 那么你必须支付虚拟调度机制的费用.或者如果类中没有数据,在这种情况下,类仍然需要占用一些空间(这又是因为每个对象在内存中必须有唯一的地址).
函数不是对象的数据布局的一部分.它们只是对象心理概念的一部分.该函数被转换为代码,该代码将对象的实例作为附加参数,并且相应地转换对成员函数的调用以传递该对象.
数据成员的数量无关紧要.比较苹果和苹果; 如果你有一个10个整数的类,那么它占用10个整数的相同空间.
无论它们是什么,在堆栈上分配东西都是免费的.编译器将所有局部变量的大小相加,并一次调整堆栈指针以为它们腾出空间.在内存成本中分配空间,但成本可能更多地取决于分配数量而不是分配的空间量.
好吧,让我们全力以赴.我可以通过完全优化来编译一个更完整的示例,如下所示:
void use(int &);
class classWithInt
{
public:
classWithInt() : someInt(){}
int someInt;
};
class podWithInt
{
public:
int someInt;
};
int main() {
int foo;
classWithInt bar;
podWithInt baz;
use(foo);
use(bar.someInt);
use(baz.someInt);
return 5;
}
Run Code Online (Sandbox Code Playgroud)
这是我从gcc-llvm得到的输出
; ModuleID = '/tmp/webcompile/_21792_0.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-linux-gnu"
%struct.classWithInt = type { i32 }
define i32 @main() {
entry:
%foo = alloca i32, align 4 ; <i32*> [#uses=1]
%bar = alloca %struct.classWithInt, align 8 ; <%struct.classWithInt*> [#uses=1]
%baz = alloca %struct.classWithInt, align 8 ; <%struct.classWithInt*> [#uses=1]
%0 = getelementptr inbounds %struct.classWithInt* %bar, i64 0, i32 0 ; <i32*> [#uses=2]
store i32 0, i32* %0, align 8
call void @_Z3useRi(i32* %foo)
call void @_Z3useRi(i32* %0)
%1 = getelementptr inbounds %struct.classWithInt* %baz, i64 0, i32 0 ; <i32*> [#uses=1]
call void @_Z3useRi(i32* %1)
ret i32 5
}
declare void @_Z3useRi(i32*)
Run Code Online (Sandbox Code Playgroud)
每种情况都有一些差异.在最简单的情况下,POD类型与plain int的区别仅在于一种方式,它需要不同的对齐方式,它是8字节对齐而不是仅仅4字节.
另一个值得注意的事情是POD和裸int没有被初始化.它们的存储空间正好从堆栈的荒野中使用.非pod类型具有非平凡的构造函数,在实例可用于其他任何操作之前,会导致存储零.