为什么使用默认构造函数“ {}”而不是“ = default”会产生性能差异?

问题描述 投票:0回答:2

我最近注意到我在性能方面受到打击,因为我在声明默认的构造函数,如:

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%时间

更改编译器设置似乎会更改结果,有时会完全翻转它。但是我不明白的是为什么它如此重要?

c++ performance constructor compiler-optimization default-constructor
2个回答
1
投票

Foo() = default;平凡的构造函数。

Foo() {}是一个用户定义的构造函数,根据定义,即使它们为空,用户定义的构造函数也绝不简单。

另请参见Trivial default constructorstd::is_trivial

预计在启用]编译器优化时,琐碎的构造函数可能比用户提供的构造函数更快。


0
投票

Foo() = default;Foo() {};不同。前者是琐碎的默认构造函数,而后者是默认构造函数的自定义版本,除了默认内容外什么也不做。

© www.soinside.com 2019 - 2024. All rights reserved.