Improve Performance of C++ Codes (1) -- 使用初始化列表还是赋值语句?

就提高程序的性能/效率而言,上层的平台/架构/算法/数据结构当然重要,然而也不能忽视代码本身的性能优化,即为了让编译器将你写的高级语言的代码翻译成尽量高效的机器代码,这方面也是我很感兴趣的领域,下面就记录一些improve performance of c++ codes的方方面面,希望从点滴做起,写出相对高效的c++codes。

条款1:
--------------------------------
Q:构造函数中使用初始化列表(Initialization list)还是赋值(Aassignment)来初始化成员?
A:尽量使用初始化列表。
--------------------------------

测试:
--------------------------------
(测试主要集中于在x86平台上的MS编译器,且是在开启编译器的最大优化功能的情况下,一般对应Release模式)
下面看个c++ test program:

//TestClass.h
class A
{
public:
    A();
    int i;
};

//TestClass.cpp
#include "TestClass.h"

A::A()
{
    i = 0;
}

//LGVector.h
#include "TestClass.h"

class LGVector
{
public:
    // constructor
    LGVector(){};
    LGVector(A a);

private:
    int i;
    A a;    
};


//LGVector.cpp
#include "TestClass.h"

// Initializaton list
LGVector::LGVector(A a) : a(a)
{
}

// Assignment
//LGVector::LGVector(A a) : a(a)
//{
//    a = a;
//}

//main.cpp
#include "LGVector.h"

int main(int argc, char* argv[])
{    
    A a1;
    a1.i = 10;

    LGVector v1(a1);

    return 0;
}


下面是LGVector构造函数的x86 Assembly codes:

初时化列表:(x86, VC++ 6.0, Release, Optimization: Maximize)

_a$ = 8
??0LGVector@@QAE@VA@@@Z PROC NEAR            ; LGVector::LGVector, COMDAT

; 14   : {    

    mov    eax, ecx
    mov    ecx, DWORD PTR _a$[esp-4]  // 不会调用A的构造函数
    mov    DWORD PTR [eax+4], ecx

; 15   : }

    ret    4


赋值操作:(x86, VC++ 6.0, Release, Optimization: Maximize)

_a$ = 8
??0LGVector@@QAE@VA@@@Z PROC NEAR            ; LGVector::LGVector, COMDAT

; 7    : {

    push    esi
    mov    esi, ecx
    push    edi
    lea    edi, DWORD PTR [esi+4]
    mov    ecx, edi
    call    ??0A@@QAE@XZ                ; A::A // 会调用A的构造函数,注意:并没有分配额外的内存来创

建额外的对象,只是将当前对象的的子对象a的指针(edi)传递到A:A()中,做一些初时化。performance的下降只在于A:A()的调用。

; 8    :     this->a = a;

    mov    eax, DWORD PTR _a$[esp+4]
    mov    DWORD PTR [edi], eax

; 9    : }

    mov    eax, esi
    pop    edi
    pop    esi
    ret    4

--------------------------------

小结:
--------------------------------
VC++ 6.0下:
在构造函数中,推荐使用初时化列表来初始化成员,可以避免成员的构造函数的调用,提高performance,但只针对
non built-in/instinctive types,因为built-in/instinctive types没有构造函数。

在VC++2005:
貌似两者performance一样,赋值操作来初始化成员也不会调用成员的构造函数。

--------------------------------

你可能感兴趣的:(Improve Performance of C++ Codes (1) -- 使用初始化列表还是赋值语句?)