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

What is performance difference between different class or struct initialization methods?

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

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;

它们之间有区别吗?

哪个更好用?

TL;DR 除非你知道你必须关心,否则不要关心这些琐事。如果必须,则需要分析具体装配。

总的来说,从纯语言的角度来看,这样的问题是没有意义的。对于它的价值,c++ 编译器可以根据需要削弱性能。任何表现出相同行为的程序都是合法的,性能不是可见的效果。

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

全部学习: 我将在 godbolt compiler explorer

上使用 clag 7.0.0

你的情况很奇怪,因为它定义了全局 values.For 默认优化选项:

  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

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

而对于 -O2 物体溶解了。