memset 和 bzero的效率测试。

原创 2012年03月28日 17:31:31

一直有人提出,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、对于有变量初始化的类型,避免使用清零动作


相关文章推荐

memset效率测试

刚刚AC了一题,需要将数组部分初始化为零,为了简单我就用memset将整个数组置零了,在我印象中memset函数的速度是快得惊人的,没想到居然超时了,让我不得不重新审视memset的效率和我那想当然的...
  • lalor
  • lalor
  • 2012年02月19日 14:06
  • 6482

memset()的效率以及源码分析

void *memset(void *s, int ch, size_t n); 作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数...

GCC源码分析(一)——介绍与安装

一、GCC的作用和运行机制     GCC是Linux下重要的编译工具,用法这里就不说了,满大街都找得到。这里我重点介绍GCC的运作机制,作为代码分析的铺垫。全篇使用C语言子部件来作分析,因为我对其他...

Boost 的 STL Container 切割工具(上):split

这篇蛮好的,原帖:http://viml.nchc.org.tw/blog/paper_info.php?CLASS_ID=1&SUB_ID=1&PAPER_ID=209 這一篇最初的目...
  • yacper
  • yacper
  • 2012年09月27日 17:21
  • 6238

bzero, memset ,setmem 区别

bzero   原型: extern void bzero(void *s, int n); 用法: #include      功能:置字节字符串s的前n个字节为零。   ...

ReadCode-001: memcpy memset bzero

#include #include #include struct student{ int age; char name[15]; }; typedef struct student ...

给程序计时2-bzero & memset置零的性能比较

 关于字符数组的初始化,在项目的压力测试中,发现性能明显下降,变怀疑在程序中的若干临时字符数组的初始化(使用bzero)身上。于是修改为首个字符置零的方式而非全部置零的方式初始化,响应得到明显的提升。...

bcopy和memcpy、bzero和memset、bcmp和memcmp的差别

bcopy和memcpy、bzero和memset、bcmp和memcmp的区别

memset+与bzero+置0的性能比较

小程序测试 #include #include #include #include #define TIMEDIFF(s, e) (((e.tv_sec)-(s.tv_sec))*10...

bzero()与 memset()等的区别

BZERO()等的区别 bzero   原型: extern void bzero(void *s, int n); 用法: #include      功能:置字节字符串...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:memset 和 bzero的效率测试。
举报原因:
原因补充:

(最多只允许输入30个字)