- 论坛徽章:
- 1
|
昨天上网,看到一些代码用calloc函数写的。申请内存的函数,平时不常用。因为不常用,所以见了便想它为什么不常用呢?是不是它和malloc+memset函数的效率有差别啊?所以写了验证程序,一看,果然如此,calloc函数的效率要比malloc+memset函数的效率低一点。测试如下:
环境:
- Red Hat Linux release 8.0 (Psyche)
- Kernel 2.4.18-14smp on an i686
- login: yangwl
- Password:
复制代码
测试办法:用calloc函数申请100个字节的空间,申请1亿次,记时。用malloc+memset函数完成同样的工作,记时。比较两次记时的大小。
自己猜想后简单的测试代码及结果:
- [yangwl:/home/users50/yangwl/test]$ cat time.c
- #include <stdio.h>;
- #include <stdlib.h>;
- #include <time.h>;
- #include <string.h>;
- int main(void) {
- int i;
- char *p;
- time_t t;
- t = time(0);
- printf("begin...\n");
- for ( i = 0; i < 100000000; i++) {
- #ifdef CA
- p = (char *)calloc(100,sizeof(char));
- #endif
- #ifdef MA
- p = (char *)malloc(100*sizeof(char));
- memset(p,0,100);
- #endif
- if ( p == NULL ) {
- printf("calloc error!\n");
- exit(1);
- }
- free(p);
- }
- t = time(0) - t;
- printf("%ld\n",t);
- exit(0);
- }
- [yangwl:/home/users50/yangwl/test]$ gcc -o ca time.c -O2 -DCA
- [yangwl:/home/users50/yangwl/test]$ gcc -o ma time.c -O2 -DMA
- [yangwl:/home/users50/yangwl/test]$ ./ca
- begin...
- 33
- [yangwl:/home/users50/yangwl/test]$ ./ma
- begin...
- 32
- [yangwl:/home/users50/yangwl/test]$ ./ca
- begin...
- 33
- [yangwl:/home/users50/yangwl/test]$ ./ma
- begin...
- 31
- [yangwl:/home/users50/yangwl/test]$ ./ca
- begin...
- 34
- [yangwl:/home/users50/yangwl/test]$ ./ma
- begin...
- 32
- [yangwl:/home/users50/yangwl/test]$
复制代码
怕自己因为测的次数少,结果不正确,所以写一个长期测试的程序,下班放在服务器上运行。将结果写入文件,测试代码及结果如下:
- [yangwl:/home/users50/yangwl/test]$ cat time.c
- #include <stdio.h>;
- #include <stdlib.h>;
- #include <time.h>;
- #include <string.h>;
- time_t ma(FILE *);
- time_t ca(FILE *);
- int main(void) {
- int i,
- count = 0,
- true = 0,
- false = 0;
- time_t t,
- tmp;
- struct tm *tforp;
- FILE *fp1,*fp2;
- fp1 = fopen("./log1","w");
- if ( fp1 == NULL ) {
- printf("log1 open error!\n");
- exit(1);
- }
- fp2 = fopen("./log2","w");
- if ( fp2 == NULL ) {
- printf("log2 open error!\n");
- exit(1);
- }
- t = time(0);
- tforp = localtime(&t);
- fprintf(fp1,"begin time:%d-%d-%d %d:%d:%d\n",tforp->;tm_year+1900,tforp->;tm_mon+1,tforp->;tm_mday,
- tforp->;tm_hour,tforp->;tm_min,tforp->;tm_sec);
- fprintf(fp2,"begin time:%d-%d-%d %d:%d:%d\n",tforp->;tm_year+1900,tforp->;tm_mon+1,tforp->;tm_mday,
- tforp->;tm_hour,tforp->;tm_min,tforp->;tm_sec);
- for ( i = 0; i < 10*60; i++ ) {
- tmp = ca(fp2)-ma(fp2);
- fprintf(fp2," %ld",tmp);
- tmp >; 0 ? true++ : false++;
- count++;
- }
- fprintf(fp1,"true:%d\nfalse:%d\ncount:%d\n",true,false,count);
- t = time(0);
- tforp = localtime(&t);
- fprintf(fp1,"end time:%d-%d-%d %d:%d:%d\n",tforp->;tm_year+1900,tforp->;tm_mon+1,tforp->;tm_mday,
- tforp->;tm_hour,tforp->;tm_min,tforp->;tm_sec);
- fprintf(fp2,"end time:%d-%d-%d %d:%d:%d\n",tforp->;tm_year+1900,tforp->;tm_mon+1,tforp->;tm_mday,
- tforp->;tm_hour,tforp->;tm_min,tforp->;tm_sec);
- fclose(fp1);
- fclose(fp2);
- exit(0);
- }
- time_t ma(FILE *fp2) {
- int i;
- char *p;
- time_t t;
- t = time(0);
- for ( i = 0; i < 100000000; i++) {
- p = (char *)malloc(100*sizeof(char));
- memset(p,0,100);
- if ( p == NULL ) {
- fprintf(fp2,"calloc error!\n");
- exit(1);
- }
- free(p);
- }
- t = time(0)-t;
- return t;
- }
- time_t ca(FILE *fp2) {
- int i;
- char *p;
- time_t t;
- t = time(0);
- for ( i = 0; i < 100000000; i++) {
- p = (char *)calloc(100,sizeof(char));
- if ( p == NULL ) {
- fprintf(fp2,"calloc error!\n");
- exit(1);
- }
- free(p);
- }
- t = time(0)-t;
- return t;
- }
- [yangwl:/home/users50/yangwl/test]$ cat log1
- begin time:104-8-8 19:19:22
- true:586
- false:14
- count:600
- end time:70-0-1 21:1:21
- [yangwl:/home/users50/yangwl/test]$ cat log2
- begin time:104-8-8 19:19:22
- 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1end time:70-0-1 21:1:21
- [yangwl:/home/users50/yangwl/test]$
复制代码
结果:果然calloc函数的效率要稍微低一点,平均差2sec,少数差1sec,极少可以做到几乎不差。要注意,结果只能精确到sec。
猜想原因:有一个很明显的能看出来的差别是,calloc函数要在函数运行中计算总共开辟多大空间。而malloc函数的参数只有一个,在上面的程序钟,这个参数是一个可以在编译的过程中就确定大小的表达式,因此能事先确定开辟空间的大小。但是,性能的差别仅仅在于一个乘法操作吗?
bug:呵呵,大家可以看出来,log文件中的日期时间有问题。是因为忘记了localtime的用法,以及取时间语句的一个错误,昨天着急写程序所致,不过并不影响结果。
意外:本来一次循环应该耗时1分多钟,所以我定了600次循环,本来以为可以让它运行一晚上,结果看log,2个小时不到就结束了,不知道为什么,是服务器在晚上的运算速度提高了?还是经常性的“分配”“释放”,系统的内存管理机制习惯了这样的动作导致“熟能生巧”了?[/code] |
|