不同的类或结构初始化方法之间的性能差异是什么?

时间:2018-10-08 10:52:12

标签: c++ class struct initialization member-variables

在c ++中,我们有不同类型的初始化类或结构成员变量 其中之一是:

struct foo {
    foo() : a(true), b(true), c(true) {}
    bool a;
    bool b;
    bool c;
 } bar;

另一个是:

struct foo {
    bool a = true;
    bool b = true;
    bool c = true;
 } bar;

它们之间有区别吗?

使用哪个更好?

1 个答案:

答案 0 :(得分:0)

TL; DR 除非您知道必须如此,否则不要在乎这些琐碎的小事。并且,如果需要,您需要分析混凝土装配。

通常从纯语言的角度来看,这样的问题是没有道理的。就其价值而言,C ++编译器可以根据需要降低性能。任何表现出相同行为的程序都是合法的,并且性能不是可见的效果。

仅在使用特定编译器和配置(尤其是优化)的具体组装的具体应用中,谈论性能才有意义。

全面研究: 我将在godbolt compiler explorer

上使用clag 7.0.0

您的情况很奇怪,因为它定义了全局值。对于默认优化选项:

  1. 生成了c'tor,并将对象存储为零
  2. 没有代码,对象生成为3个

显然,选项2似乎更好:

__cxx_global_var_init:                  # @__cxx_global_var_init
        push    rbp
        mov     rbp, rsp
        movabs  rdi, offset bar
        call    foo::foo() [base object constructor]
        pop     rbp
        ret
foo::foo() [base object constructor]:  # @foo::foo() [base object constructor]
        push    rbp
        mov     rbp, rsp
        mov     qword ptr [rbp - 8], rdi
        mov     rdi, qword ptr [rbp - 8]
        mov     byte ptr [rdi], 1
        mov     byte ptr [rdi + 1], 1
        mov     byte ptr [rdi + 2], 1
        pop     rbp
        ret
_GLOBAL__sub_I_example.cpp:             # @_GLOBAL__sub_I_example.cpp
        push    rbp
        mov     rbp, rsp
        call    __cxx_global_var_init
        pop     rbp
        ret
bar:
        .zero   3

bar2:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

不过,使用-O1可以减少代码的差异:

bar:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

bar2:
        .byte   1                       # 0x1
        .byte   1                       # 0x1
        .byte   1                       # 0x1

在程序中使用foo作为类型时,-O0-O1的情况都会生成ctor(每种情况下的ctor相同,每个优化级别都不同)。参见:https://godbolt.org/z/0il6ou

对于-O2,对象会溶解。