最近看书用到了程序段计时器,顺便就写一小段的代码来玩玩,结果发现一个有趣的现象,将一个简单的循环从main函数移出,并包装到一个单独的函数,然后从main调用该函数,结果所使用的时间反而少了。按理来说,函数调用会涉及到多次的内存读写,应该是时间会延长,事实却相反。
小二,上代码!
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
struct timevale {
long tv_sec;
long tv_usec;
};
double getSum (int len){
int i = 0;
int sum = 0;
for(i = 0; i < len; i++){
sum += 1;
}
}
main (){
struct timevale starttime, endtime; //use gettimeofday();
clock_t beg, end; //use clock() to get time
int len = 10000000;
double sum = 0;
int sumInt = 0;
int i;
scanf("%d", &len); //get the length.
beg = clock();
for(i = 0; i < len; i++){
sum += 1;
}
end = clock();
double cost = (double)(end - beg) / CLOCKS_PER_SEC;
printf("sum %lf\n", sum);
printf("used time: %lf\n", cost);
printf("\n use function : \n ");
beg = clock();
getSum(len);
end = clock();
cost = (double)(end - beg) / CLOCKS_PER_SEC;
printf("sum %lf\n", sum);
printf("used time: %lf\n", cost);
gettimeofday(&starttime,0);
for(i = 0; i < len; i++){
sum += 1;
}
gettimeofday(&endtime,0);
double timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec;
printf("------------ \n used time: %lf\n", timeuse);
gettimeofday(&starttime,0);
getSum(len);
gettimeofday(&endtime,0);
timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec;
printf("------------ \n used time: %lf\n", timeuse);
}
结果:
# ./timeCost
100000000
sum 100000000.000000
used time: 0.370000 <---- for 循环 in main
use function :
sum 100000000.000000
used time: 0.230000 <---- 函数调用
------------
used time: 376234.000000 //微秒 <---- for 循环 in main
------------
used time: 225131.000000
#
========2014-01-17
以上代码有一点问题,在于main函数中定义了sum 为double,而函数中定义为int,因此导致了编译后,main中的for循环用到了浮点寄存器%xmm1等,导致了时间的增加。
将函数更新之后,问题就出现了,函数调用的时间还是比直接写在main里面的短:
# ./timeCost
700000000
sum 700000000
used time: 1.720000
use function :
used time: 1.580000
------------
used time: 1732559.000000
------------
used time with function: 1581448.000000
同时,反编译后得到的汇编代码中可以看到,main与getSum中的循环体是一样的:
0000000000400448 <getSum>:
400464: eb 08 jmp 40046e <getSum+0x26>
400466: 83 45 fc 01 addl $0x1,0xfffffffffffffffc(%rbp)
40046a: 83 45 f8 01 addl $0x1,0xfffffffffffffff8(%rbp)
40046e: 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%eax
400471: 3b 45 ec cmp 0xffffffffffffffec(%rbp),%eax
400474: 7c f0 jl 400466 <getSum+0x1e>
0000000000400478 <main>:
400495: eb 08 jmp 40049f <main+0x27>
400497: 83 45 f8 01 addl $0x1,0xfffffffffffffff8(%rbp)
40049b: 83 45 fc 01 addl $0x1,0xfffffffffffffffc(%rbp)
40049f: 8b 45 fc mov 0xfffffffffffffffc(%rbp),%eax
4004a2: 3b 45 f4 cmp 0xfffffffffffffff4(%rbp),%eax
4004a5: 7c f0 jl 400497 <main+0x1f>
Then why????
小二,上代码!
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
struct timevale {
long tv_sec;
long tv_usec;
};
double getSum (int len){
int i = 0;
int sum = 0;
for(i = 0; i < len; i++){
sum += 1;
}
}
main (){
struct timevale starttime, endtime; //use gettimeofday();
clock_t beg, end; //use clock() to get time
int len = 10000000;
double sum = 0;
int sumInt = 0;
int i;
scanf("%d", &len); //get the length.
beg = clock();
for(i = 0; i < len; i++){
sum += 1;
}
end = clock();
double cost = (double)(end - beg) / CLOCKS_PER_SEC;
printf("sum %lf\n", sum);
printf("used time: %lf\n", cost);
printf("\n use function : \n ");
beg = clock();
getSum(len);
end = clock();
cost = (double)(end - beg) / CLOCKS_PER_SEC;
printf("sum %lf\n", sum);
printf("used time: %lf\n", cost);
gettimeofday(&starttime,0);
for(i = 0; i < len; i++){
sum += 1;
}
gettimeofday(&endtime,0);
double timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec;
printf("------------ \n used time: %lf\n", timeuse);
gettimeofday(&starttime,0);
getSum(len);
gettimeofday(&endtime,0);
timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec;
printf("------------ \n used time: %lf\n", timeuse);
}
结果:
# ./timeCost
100000000
sum 100000000.000000
used time: 0.370000 <---- for 循环 in main
use function :
sum 100000000.000000
used time: 0.230000 <---- 函数调用
------------
used time: 376234.000000 //微秒 <---- for 循环 in main
------------
used time: 225131.000000
#
========2014-01-17
以上代码有一点问题,在于main函数中定义了sum 为double,而函数中定义为int,因此导致了编译后,main中的for循环用到了浮点寄存器%xmm1等,导致了时间的增加。
将函数更新之后,问题就出现了,函数调用的时间还是比直接写在main里面的短:
# ./timeCost
700000000
sum 700000000
used time: 1.720000
use function :
used time: 1.580000
------------
used time: 1732559.000000
------------
used time with function: 1581448.000000
同时,反编译后得到的汇编代码中可以看到,main与getSum中的循环体是一样的:
0000000000400448 <getSum>:
400464: eb 08 jmp 40046e <getSum+0x26>
400466: 83 45 fc 01 addl $0x1,0xfffffffffffffffc(%rbp)
40046a: 83 45 f8 01 addl $0x1,0xfffffffffffffff8(%rbp)
40046e: 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%eax
400471: 3b 45 ec cmp 0xffffffffffffffec(%rbp),%eax
400474: 7c f0 jl 400466 <getSum+0x1e>
0000000000400478 <main>:
400495: eb 08 jmp 40049f <main+0x27>
400497: 83 45 f8 01 addl $0x1,0xfffffffffffffff8(%rbp)
40049b: 83 45 fc 01 addl $0x1,0xfffffffffffffffc(%rbp)
40049f: 8b 45 fc mov 0xfffffffffffffffc(%rbp),%eax
4004a2: 3b 45 f4 cmp 0xfffffffffffffff4(%rbp),%eax
4004a5: 7c f0 jl 400497 <main+0x1f>
Then why????