C++宏，普通函数，内联函数的运行速度以及三者的差异

</pre>下面论证一下：c/c++中 运行速度对比，宏>内联函数>普通函数   以及3者的差异<p></p><p></p><p>首先简单的代码验证下：</p><p>#include <iostream></p><pre name="code" class="cpp">
#include <boost/timer.hpp>

#define  _SUM(x,y) x+y
using std::cout;
using std::endl;
using boost::timer;

const int MAX_ARR_SIZE = 50000;

int sum1(int a,int b)
{
return a + b;
}

inline int sum2(int a,int b)
{
return a + b;
}

int main(void)
{
long iarray1[MAX_ARR_SIZE];
long iarray2[MAX_ARR_SIZE];

timer t1;
cout<<t1.elapsed()<<endl;
for (size_t star1(0); star1 < MAX_ARR_SIZE;++star1)
{
iarray1[star1] = star1;
}

for (size_t star1(0); star1 < MAX_ARR_SIZE; ++star1)
{
iarray2[star1] = star1;
}
double tt1 = t1.elapsed();
cout << t1.elapsed()<<endl;

for (size_t star1(0); star1 < MAX_ARR_SIZE; ++star1)
{
long result = sum1(iarray1[star1], iarray2[star1]);
if (star1 == MAX_ARR_SIZE-1)
{
cout << "非内联:" << iarray1[star1] << " + " << iarray2[star1]<<" = " << result << endl;
}
}
cout << "执行非内联的sum1的时间为：" << t1.elapsed() - tt1<<endl;

double tt2 = t1.elapsed();

for (size_t star1(0); star1 < MAX_ARR_SIZE; ++star1)
{
long result = sum2(iarray1[star1], iarray2[star1]);
if (star1 == MAX_ARR_SIZE - 1)
{
cout << "内联:" << iarray1[star1] << " + " << iarray2[star1] << " = " << result << endl;
}
}
cout << "执行内联的sum2的时间为：" << t1.elapsed() - tt2 << endl;

double tt3 = t1.elapsed();

for (size_t star1(0); star1 < MAX_ARR_SIZE; ++star1)
{
long result = _SUM(iarray1[star1], iarray2[star1]);
if (star1 == MAX_ARR_SIZE - 1)
{
cout << "宏:" << iarray1[star1] << " + " << iarray2[star1] << " = " << result << endl;
}
}
cout << "执行宏的_SUM的时间为：" << t1.elapsed() - tt3 << endl;

return 0;
}

0
0.047

test1.c    这个测试下宏

#include<stdio.h>

#define _SUM(x,y) x+y

void main()
{
printf("%d\n",_SUM(5,6));
}

#gcc -E test1.c -o test1.i

...以上省略啊（包含的头文件加进来）

# 2 "test1.c" 2

void main()
{
printf("%d\n",5 +6);
}

gcc –S test1.i –o test1.s

.file    "test1.c"
.section    .rodata
.LC0:
.string    "%d\n"
.text
.globl main
.type    main, @function
main:
pushl    %ebp
movl    %esp, %ebp
andl    $-16, %esp subl$16, %esp
movl    $.LC0, %eax movl$11, 4(%esp)       #在这里我们的表达式在编译时期计算出来，并转换为了立即数
movl    %eax, (%esp)
call    printf
leave
ret
.size    main, .-main
.ident    "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section    .note.GNU-stack,"",@progbits

test2.c

#include<stdio.h>

int sum(int x,int y)
{
return x+y;
}

void main()
{
printf("%d\n",sum(5,6));
}

gcc -E test2.c -o test2.i

....

# 2 "test2.c" 2

int sum(int x,int y)
{
return x+y;
}

void main()
{
printf("%d\n",sum(5,6));
}

gcc -S test2.i -o test2.S

.file    "test2.c"
.text
.globl sum
.type    sum, @function
sum:
pushl    %ebp
movl    %esp, %ebp
movl    12(%ebp), %eax
movl    8(%ebp), %edx
leal    (%edx,%eax), %eax
popl    %ebp
ret
.size    sum, .-sum
.section    .rodata
.LC0:
.string    "%d\n"
.text
.globl main
.type    main, @function
main:
pushl    %ebp
movl    %esp, %ebp
andl    $-16, %esp subl$16, %esp
movl    $6, 4(%esp) movl$5, (%esp)
call    sum                             #在这个地方产生了函数调用，也是使程序运行速度下降的原因
movl    $.LC0, %edx movl %eax, 4(%esp) movl %edx, (%esp) call printf leave ret .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits 可见上面程序产生了函数掉用，即参数的压栈 下面是测试代码3:测试内联函数的 test3.c #include<stdio.h> inline int sum(int x, int y) __attribute__((always_inline)); //注意这里加上编译属性，让编译器始终展开此内联函数，否则编译出来后跟普通函数没啥区别 inline int sum(int x, int y) { return x + y; } void main() { printf("%d\n",sum(5,6)); } 同样先预编译： gcc -E test3.c -o test3.i 得到下面代码： test3.i .... # 2 "test3.c" 2 inline int sum(int x, int y) __attribute__((always_inline)); inline int sum(int x, int y) { return x + y; } void main() { printf("%d\n",sum(5,6)); } 由此可见，内联函数的展开不管预编译的事情，明显是在编译时展开的 下面将 test3.i编译 gcc -S tets3.i -o test3.S 得到下面的代码 test3.S: .file "test4.c" .text .globl sum .type sum, @function sum: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax movl 8(%ebp), %edx leal (%edx,%eax), %eax popl %ebp ret .size sum, .-sum .section .rodata .LC0: .string "%d\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl$-16, %esp
subl    $32, %esp movl$5, 28(%esp)
movl    $6, 24(%esp) movl 24(%esp), %eax movl 28(%esp), %edx leal (%edx,%eax), %eax #这里可以看出，没有产生函数调用，而是将sum的代码展开在此 movl %eax, %edx movl$.LC0, %eax
movl    %edx, 4(%esp)
movl    %eax, (%esp)
call    printf
leave
ret
.size    main, .-main
.ident    "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section    .note.GNU-stack,"",@progbits