不同的类或结构初始化方法之间的性能差异是什么?
What is performance difference between different class or struct initialization methods?
我们在 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
你的案例很奇怪,因为它定义了全局值。对于默认优化选项:
- 生成 C'Tor 并将对象存储为零
- 没有代码,对象生成为 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
as 类型时,会为两种情况生成-O0
和-O1
ctor(每种情况的 ctor 相同,每个优化级别不同(。请参阅:https://godbolt.org/z/0il6ou
对于-O2
,对象被溶解。
相关文章:
- 是否总是可以将使用递归编写的程序重写为不使用递归的程序C++,性能观点是什么?
- 不同的类或结构初始化方法之间的性能差异是什么?
- 并行性能不佳的原因是什么?
- 标准库容器最简单、性能差的哈希类是什么?
- 与保留模式GUI相比,使用直接模式GUI的性能含义是什么?
- GSL 的预期 (cond) 对运行时施加的性能影响是什么?
- F#性能:是什么让这个代码如此缓慢
- 将特征矩阵转换为 c 数组以便我可以使用 gsl 的性能高效方法是什么
- 链接分配的性能含义是什么
- 造成这种性能差异的原因可能是什么
- 函数指针:从性能的角度来看,简单的规范使用是否不好?如果是这样的话,c++11的替代方案是什么
- 将字符串写入文件的最具性能的方法是什么
- 使用 std::vector<boost::shared_ptr<Base_Class>> 或 boost::p tr_vector 的性能注意事项是什么<Base>
- OpenMP线程多于工作对性能的影响是什么?
- 用c++估计代码的时间性能最准确的方法是什么?
- 这样的继承对性能的影响是什么?
- 查找仅在性能测试下发生的堆损坏的最佳方法是什么?
- 在保持良好的面向对象设计的同时重用代码以提高性能的最佳方法是什么?
- 测试值是否在阈值范围内的最佳方法(性能方面)是什么
- strand.post 和strand.wrap之间的性能差异是什么?