初始化每个班级成员时的绩效问题?

时间:2018-02-19 13:04:13

标签: c++ eclipse initialization initializer-list

我认为这个问题是关于初始化的一般观点,它已经解答了很多:

Should constructor initialize all the data members of the class?

但是,当我的类有100个成员并且使用{}命令初始化每个成员时,我没有找到关于可能的性能问题的任何内容,只是因为Eclipse警告我未初始化的成员:< / p>

  

成员'foo'未在此构造函数中初始化

我的问题:每次对这个类进行实例化时,每个成员的初始化都会导致每个成员[&gt; 50]导致性能问题?

更新:由于第一条评论:我一般都在问。 Eclipse在我的项目中警告我9次分为4个类!

1 个答案:

答案 0 :(得分:0)

这里我的结果用gcc运行。

我用不同的班级成员测试了它[5次并取平均值]但是有100'000'000的实例化。

这有点棘手,因为我使用了最高优化级-O3因此我不得不避免编译器优化代码。

有100名成员:

Initialized class members:      4'484 msec
Not initialized class members:     50 msec

有25名成员:

Initialized class members:      1'146 msec
Not initialized class members:     50 msec // as expected it didn't change

拥有500名成员:

Initialized class members:     22'129 msec
Not initialized class members:     50 msec // as expected it didn't change

我的结论是:

正常情况下 - 没有 在初始化所有类成员时出现性能问题。在正常情况下使用 我的意思是当有一个函数[与其他代码]进行100'000'000次迭代时,成员初始化实际上不计算。

如评论所述,一个好的设计不应该有这么多的班级成员 - 我只是一般的好奇。

<强> PS:

我检查了汇编程序列表 - 当然 - 确实在初始化版本中,gcc使用int初始化了每个movq $0, 40(%rsp)成员 - 40是堆栈中的位置。

#include <stdlib.h>
#include <stdio.h>
#include <chrono>
#include <ctime>
#include <utility>

template<typename TimeT = std::chrono::microseconds>
class measure
{
public:
    template<typename F, typename ...Args>
    static typename TimeT::rep execution(F func, Args&&... args)
    {
        auto start = std::chrono::system_clock::now();
        func(std::forward<Args>(args)...);
        auto duration = std::chrono::duration_cast< TimeT> 
                                (std::chrono::system_clock::now() - start);

        return duration.count();
    }
};

class foo
{
   // for uninitialized version remove the {}
   size_t mainValue {};
   size_t classMember0 {};
   ...
   size_t classMember499 {};

public:
    foo( size_t value ) : mainValue (value + 4660) {};
    auto getMainValue() -> size_t { return mainValue; };
};

auto runCode( size_t iterationCount ) -> void
{
    size_t someValue {};
    for ( size_t j = 0 ; j < iterationCount ; ++j )
    {
        foo MyFoo (iterationCount);
        someValue += MyFoo.getMainValue();
    }
    printf( "Result=%ld\n", someValue );   // that the whole code isn't optimized away...
}

int main( int argc, char * argv [] )
{
    if ( argc != 2 )
    {
        printf( "Usage: %s <Start-Value>\n", argv [0] );
        return 0;
    }

    size_t variableValue = (size_t) atof( argv [1] );
    auto threadExecutionTime = measure<>::execution( [&] () { runCode( variableValue ); } );

    printf( "Total execution time was %.3f milliseconds. %s",
                threadExecutionTime / 1000. );
}