【发布时间】:2019-12-10 06:34:01
【问题描述】:
我最近注意到我的性能受到了影响,因为我声明了一个默认构造函数,例如:
Foo() = default;
而不是
Foo() {}
(仅供参考,我需要显式声明它,因为我还有一个可变参数构造函数,否则会覆盖默认构造函数)
这对我来说似乎很奇怪,因为我认为这两行代码是相同的(好吧,只要默认构造函数是可能的。如果默认构造函数是不可能的,第二行代码会产生错误并且第一个将隐式删除默认构造函数。'不是我的情况!)。
好的,所以我做了一个小测试器,结果因编译器而异,但在某些设置下,我得到一致的结果,一个比另一个更快:
#include <chrono>
template <typename T>
double TimeDefaultConstructor (int n_iterations)
{
auto start_time = std::chrono::system_clock::now();
for (int i = 0; i < n_iterations; ++i)
T t;
auto end_time = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end_time - start_time;
return elapsed_seconds.count();
}
template <typename T, typename S>
double CompareDefaultConstructors (int n_comparisons, int n_iterations)
{
int n_comparisons_with_T_faster = 0;
for (int i = 0; i < n_comparisons; ++i)
{
double time_for_T = TimeDefaultConstructor<T>(n_iterations);
double time_for_S = TimeDefaultConstructor<S>(n_iterations);
if (time_for_T < time_for_S)
++n_comparisons_with_T_faster;
}
return (double) n_comparisons_with_T_faster / n_comparisons;
}
#include <vector>
template <typename T>
struct Foo
{
std::vector<T> data_;
Foo() = default;
};
template <typename T>
struct Bar
{
std::vector<T> data_;
Bar() {};
};
#include <iostream>
int main ()
{
int n_comparisons = 10000;
int n_iterations = 10000;
typedef int T;
double result = CompareDefaultConstructors<Foo<T>,Bar<T>> (n_comparisons, n_iterations);
std::cout << "With " << n_comparisons << " comparisons of " << n_iterations
<< " iterations of the default constructor, Foo<" << typeid(T).name() << "> was faster than Bar<" << typeid(T).name() << "> "
<< result*100 << "% of the time" << std::endl;
std::cout << "swapping orientation:" << std::endl;
result = CompareDefaultConstructors<Bar<T>,Foo<T>> (n_comparisons, n_iterations);
std::cout << "With " << n_comparisons << " comparisons of " << n_iterations
<< " iterations of the default constructor, Bar<" << typeid(T).name() << "> was faster than Foo<" << typeid(T).name() << "> "
<< result*100 << "% of the time" << std::endl;
return 0;
}
将上述程序与g++ -std=c++11 一起使用,我始终得到类似于以下内容的输出:
10000 次迭代的 10000 次比较 默认构造函数,Foo 比 Bar 快 4.69% 的时间 交换方向: 通过 10000 次迭代的 10000 次比较 默认构造函数,Bar 比 Foo 快 96.23% 时间
更改编译器设置似乎会改变结果,有时会完全翻转。但我无法理解的是为什么它很重要?
【问题讨论】:
-
使用
system_clock来计时并不是一个好主意。 -
@NicolBolas,我对时间的准确性不感兴趣。我感兴趣的是 Foo
可以 始终比 Bar 具有更好的性能(反之亦然)。时钟足以表明这一点。 -
您是否测试了优化的构建?否则,您的结果将毫无意义。
-
未优化的编译不是为性能而设计的。因此,衡量未优化代码的性能是一种无用的娱乐形式。
-
@n.'pronouns'm。我想你不明白我想做什么。我认为在 C++ 中声明默认构造函数的两种不同方式是相同的,但即使没有优化器,我也看到了性能差异。在这个阶段,我对性能本身并不真正感兴趣,但性能差异向我证明了两个默认构造函数似乎并不相同。
标签: c++ performance constructor compiler-optimization default-constructor