memset 和 bzero的效率测试。

一直有人提出,meset和bzero的效率问题,认为在初始化小对象的时候,bzero比memset高效一点。今天写了个测试程序,如下:

这段测试代码,是分别对4字节整数,11字节的数组,8192字节的数组进行初始化,执行1000000次,求平均值。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

static inline unsigned long long rdtsc(void)
{
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

int main()
{

    unsigned long long start , end;
    unsigned long long diff;
    unsigned long long memset_avg_diff1 , memset_avg_diff2 , memset_avg_diff3;
    unsigned long long bzero_avg_diff1, bzero_avg_diff2 , bzero_avg_diff3;
    int x , i;;
    char buf[11];
    char big_buf[8192];

    memset_avg_diff1 = memset_avg_diff2 = memset_avg_diff3 = 0;
    bzero_avg_diff1 = bzero_avg_diff2 = bzero_avg_diff3 = 0;

    for( i =0 ; i < 1000000; ++i){
    //x test 
    start = rdtsc();
    memset(&x<span style="font-family: Arial, Helvetica, sans-serif;"> , 0</span> , sizeof(x));
    end = rdtsc();

    diff = end - start;
    memset_avg_diff1 += diff;
    //printf("x memset cpu circle : %llu\n" , diff);

    start = rdtsc();
    bzero(&x , sizeof(x));
    end = rdtsc();

    diff = end - start;
    bzero_avg_diff1 += diff;
   // printf("x bzero cpu circle : %llu\n" , diff);

    //buff test
    start = rdtsc();
    memset(buf, 0, sizeof(buf));
    end = rdtsc();

    diff = end - start;
    memset_avg_diff2 += diff;
    ///printf("buf memset cpu circle : %llu\n" , diff);

    start = rdtsc();
    bzero(&buf , sizeof(buf));
    end = rdtsc();

    diff = end - start;
    bzero_avg_diff2 += diff;
    //printf("buf bzero cpu circle : %llu\n" , diff);

    //big_buff test
    start = rdtsc();
    memset(big_buf , 0, sizeof(big_buf));
    end = rdtsc();

    diff = end - start;
    memset_avg_diff3 += diff;
    ///printf("buf memset cpu circle : %llu\n" , diff);
    //printf("big buf memset cpu circle : %llu\n" , diff);

    start = rdtsc();
    bzero(&big_buf , sizeof(big_buf));
    end = rdtsc();

    diff = end - start;
    bzero_avg_diff3 += diff;
}

    memset_avg_diff1 /= 1000000;
    memset_avg_diff2 /= 1000000;
    memset_avg_diff3 /= 1000000;

    bzero_avg_diff1 /= 1000000;
    bzero_avg_diff2 /= 1000000;
    bzero_avg_diff3 /= 1000000;

    printf("x memset cpu circle : %llu\n" , memset_avg_diff1);
    printf("x bzero cpu circle : %llu\n" , bzero_avg_diff1);

    printf("buf memset cpu circle : %llu\n" , memset_avg_diff2);
    printf("buf bzero cpu circle : %llu\n" , bzero_avg_diff2);

    printf("big_buf memset cpu circle : %llu\n" , memset_avg_diff3);
    printf("big_buf bzero cpu circle : %llu\n" , bzero_avg_diff3);

    return 0;
}


测试结果:

 root@VM-Ubuntu203004:~# gcc test.c
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 51
x bzero cpu circle : 61
buf memset cpu circle : 51
buf bzero cpu circle : 62
big_buf memset cpu circle : 622
big_buf bzero cpu circle : 631
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 51
x bzero cpu circle : 61
buf memset cpu circle : 51
buf bzero cpu circle : 63
big_buf memset cpu circle : 619
big_buf bzero cpu circle : 625

root@VM-Ubuntu203004:~# gcc -O3 test.c
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 39
x bzero cpu circle : 35
buf memset cpu circle : 39
buf bzero cpu circle : 35
big_buf memset cpu circle : 2123
big_buf bzero cpu circle : 2144
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 39
x bzero cpu circle : 35
buf memset cpu circle : 39
buf bzero cpu circle : 35
big_buf memset cpu circle : 2126
big_buf bzero cpu circle : 2117

总的结论是:

1、memset还是要比bzero快,虽然在 -O3优化的情况下,初始化小对象,memset 要比bzero快些,但是不值得追究。

2、对于字串内存,尽量使用第一个字清零替代全部清零

3、对于有变量初始化的类型,避免使用清零动作


你可能感兴趣的:(优化,测试)