C++ 函数参数、返回值效率测试

来源:互联网 发布:node.js urlencoder 编辑:程序博客网 时间:2024/06/07 12:49

1.简单参数类型(寄存器能容纳) 返回值

    int& fun_int(int *i) {        (*i)++;        return *i;    }    int func_int(int *i) {        (*i)++;        return *i;    }
    int &x = fun_int(&y);0038881F  lea         eax,[y]  00388822  push        eax  00388823  call        chapter11::fun_int (03817ADh)  00388828  add         esp,4  0038882B  mov         dword ptr [x],eax      int z = fun_int(&y);0038882E  lea         eax,[y]  00388831  push        eax  00388832  call        chapter11::fun_int (03817ADh)  00388837  add         esp,4  0038883A  mov         ecx,dword ptr [eax]  0038883C  mov         dword ptr [z],ecx      int j = func_int(&k);00388846  lea         eax,[k]  00388849  push        eax  0038884A  call        chapter11::func_int (03817B2h)  0038884F  add         esp,4  00388852  mov         dword ptr [j],eax  

z的返回略坑,在这里实际上执行了两步。返回值先从dword ptr [eax] 拷贝到了寄存器ecx;然后再将ecx的值拷贝变量z。这里等于说是隐含了一个类型准换

从 int &x = fun_int(&y); 与 int j = func_int(&k); 的汇编可以看出。
简单类型是否返回引用 并不影响程序。

    class Animal {        int i;        enum{size = 10};        int k[size];    public:        void fly() {            cout << "flying.." << endl;        }        void swim() const {            cout << "swimming.." << endl;        }    };    Animal& fun_animal(Animal& ai) {        ai.fly();        return ai;    }    Animal func_animal(Animal& ai) {        ai.fly();        return ai;    }
    Animal& ai2 = fun_animal(ai);00948465  lea         eax,[ai]  00948468  push        eax  00948469  call        chapter11::fun_animal (09417D5h)  0094846E  add         esp,4  00948471  mov         dword ptr [ai2],eax      Animal ai3 = func_animal(ai);00948474  lea         eax,[ai]  00948477  push        eax  00948478  lea         ecx,[ai3]  0094847E  push        ecx  0094847F  call        chapter11::func_animal (09417DAh)  00948484  add         esp,8  

如果返回的是引用,但在使用函数时用非引用时,效率会很低。中间应该多了一次临时变量的转换

而在正常返回引用与值时,值返回多了一次lea 与push操作。

2.函数参数必然就是那个样子~啦22

    class ArgClass {        enum{size = 10};        int sz[size];    public:        ArgClass() {            memset(sz, 0, size * sizeof(int));        }        void func() {            cout << "func" << endl;        }        void func_const() const{            cout << "func const" << endl;        }    };    void funcPassByValue(ArgClass ac) {        ac.func();        ac.func_const();    }    void funcPassByRef(ArgClass& ac) {        ac.func();        ac.func_const();    }    void funcPassByConstRef(const ArgClass& ac) {        // ac.func(); func()可能对对象做出修改在这里不能使用        ac.func_const();    }

passbyvalue

    funcPassByValue(ac);00F87430  sub         esp,28h  00F87433  mov         ecx,0Ah  00F87438  lea         esi,[ac]  00F8743B  mov         edi,esp  00F8743D  rep movs    dword ptr es:[edi],dword ptr [esi]  00F8743F  call        chapter11::funcPassByValue (0F8180Ch)  00F87444  add         esp,28h  

sub esp,28h 将栈顶指针下移分配更多的内存。再将ac的地址存放在寄存器esi中,将栈顶指针存放到edi。拷贝esi的内容到edi。然后再调用函数

passbyRef

    funcPassByRef(ac);00F87447  lea         eax,[ac]  00F8744A  push        eax  00F8744B  call        chapter11::funcPassByRef (0F81811h)  00F87450  add         esp,4  

直接是地址进栈然后call,效率自然是ref高