• 【转】 memset()的效率以及源码分析


    void *memset(void *s, int ch, size_t n);
    作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
    不知道有没有像我一样把memset当作万能的初始化工具,例如:
    int arr[n];
    memset(arr,1,n*sizeof(int));
    这样得到的arr数组一定不是全0,而是16843009,下面解释原因。
    首先,变量类型的本质只是标志从某一内存地址开始读取的位数,强制转换就是改变读取位数的大小。

    下面来看memset的实现:(代码来自《C标准库》P398)

    [cpp] view plain copy
     
    1. void *(memset) (void *s,int c,size_t n)  
    2. {  
    3.     const unsigned char uc = c;  
    4.     unsigned char *su;  
    5.     for(su = s;0 < n;++su,--n)  
    6.         *su = uc;  
    7.     return s;  
    8. }  

    第3行把int类型的c转换成unsigned char类型,意味着截去c的高24位,只保留低8位。第4行把s当作unsigned char*类型,也就是说su中的每一个元素按8位计算。
    现在来看看文章开头的那个代码会做什么。
    c的二进制 : 00000000000000000000000000000001(32位)
    1、c转换为unsigned char 后:00000001(8位)
    2、将指针su(unsigned char类型)的每一元素(8位)赋值为00000001,循环4n次。
    3、memset()结束后,arr的每个元素按照int类型读取,读出来的就是1000000010000000100000001,十进制就是16843009。
    不过如果是memset(arr,0,n*sizeof(int));的话可以使用,因为32位都是0

    再来说memset()的效率问题。使用memset函数与将上面的函数代码写在自己的程序里是不一样的,C标准库中的memset对Cache的利用做了优化,具体的在《C专家编程》151页有解释(其实是我没看懂),这里给出测试:

    [cpp] view plain copy
     
    1. #include <string.h>  
    2. #define MAXSIZE 100000  
    3.   
    4. int main()  
    5. {  
    6.     char arr[MAXSIZE];  
    7.     for(int i=0;i<10000;i++)  
    8.     {  
    9.         memset(arr,'0',sizeof(arr));  
    10. //        for(int j=0;j<MAXSIZE;j++)  
    11. //            arr[0] = '0';  
    12.     }  
    13.     return 0;  
    14. }  

    程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。
    综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。

    转:http://blog.csdn.net/hackbuteer1/article/details/7343189

  • 相关阅读:
    通过USB转TTL串口下载stm32程序
    实验一:基于STM32F1的流水灯实验(库函数)
    opencv 常用头文件介绍
    OpenCV 1.0在VC6下安装与配置(附测试程序)
    在Angularjs使用中遇到的那些坑
    js和ts关于遍历的几个小总结
    angularjs的启动方式
    关于跨域和如何解决跨域问题的小结
    TypeScript(入门)
    截取字符串部分汇总
  • 原文地址:https://www.cnblogs.com/eleclsc/p/5891664.html
Copyright © 2020-2023  润新知