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

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

本文关键字:性能 是什么 之间 初始化 结构 方法      更新时间:2023-10-16

我们在 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;

它们之间有区别吗?

哪一个更好用?

TL;DR不要在乎这些琐事,除非你知道你必须这样做。如果必须,您需要分析混凝土装配。

一般来说,从纯语言的角度来看,这些问题是没有意义的。就其价值而言,如果它愿意,c ++编译器可以削弱性能。任何表现出相同行为的程序都同样合法,并且性能不是可见的效果。

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

全面研究:我将在 godbolt 编译器资源管理器上使用 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

在程序中使用fooas 类型时,会为两种情况生成-O0-O1ctor(每种情况的 ctor 相同,每个优化级别不同(。请参阅:https://godbolt.org/z/0il6ou

对于-O2,对象被溶解。