[转载]memset()的效率

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

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)

    void *(memset) (void *s,int c,size_t n)
    {
        const unsigned char uc = c;
        unsigned char *su;
        for(su = s;0 < n;++su,--n)
            *su = uc;
        return s;
    }

第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页有解释(其实是我没看懂),这里给出测试:

    #include <string.h>
    #define MAXSIZE 100000  

    int main()
    {
        char arr[MAXSIZE];
        for(int i=0;i<10000;i++)
        {
            memset(arr,‘0‘,sizeof(arr));
    //        for(int j=0;j<MAXSIZE;j++)
    //            arr[0] = ‘0‘;
        }
        return 0;
    }

程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。

总之:
1.memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动循环赋值要高的多。
2.但是,初始化一个字符数组时,在已知字符长度的情况下,采用了在数组末端补0来控制字符串长度,没有必要用memset,这样性能比较好。

[转载]memset()的效率

时间: 2024-10-07 03:24:17

[转载]memset()的效率的相关文章

c语言memset源码

c语言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() 函数的使用

第一次接触了memset() 函数. 感觉的确是一个能够高效的实现对一个array 进行一次性初始化的fancy way. 下面给出介绍: memset() 函数定义在头文件<<cstring>>中, prototype 如下: void * memset ( void * ptr, int ch, size_t num ); 函数的作用是: fill the first num bytes(注意不是element) of block of memory(由空指针ptr指向) wi

对于流程优化的处理器架构

在过去的两年里,我学到了很多的代码优化方法的同事,在此汇总了什么. 优化处理器架构可以从下面几个方向展开:高速缓存命中.指令预测.数据预取,数据对齐,内存拷贝优化,ddr访问延迟.硬件内存管理优化,指令优化.叙述工具. 缓存未命中是处理器的主要性能瓶颈之中的一个.在FSL的powerpc上,訪问一级缓存是3个时钟周期,二级是12个,3级30多个.内存100个以上.一级缓存和内存訪问速度差30多倍. 我们能够算一下,假设仅仅有一级缓存和内存,100条存取指令.100%命中和95%命中.前者300周

面向处理器结构的程序优化

近两年从同事那里学了不少代码优化方法,在此总结一下. 面向处理器结构的优化可以从以下几个方向入手:缓存命中,指令预测,数据预取,数据对齐,内存拷贝优化,ddr访问延迟,硬件内存管理优化,指令优化,编译器优化等级以及性能描述工具. 缓存未命中是处理器的主要性能瓶颈之一.在FSL的powerpc上,访问一级缓存是3个时钟周期,二级是12个,3级30多个,内存100个以上.一级缓存和内存访问速度差30多倍.我们可以算一下,如果只有一级缓存和内存,100条存取指令,100%命中和95%命中,前者300周

CF1093D Beautiful Graph

思路: 题目倒是没啥好说的,就是注意memset的效率问题.如果循环多次调用memset去初始化一个比较大的数组,那就会很费时间.就是因为这个被hack了.:( 实现: 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 const int MOD = 998244353; 6 const int MAXN = 300005; 7 8 vector<int> G[MAXN]; 9

MySQL优化之COUNT(*)效率(部分转载与个人亲测)

说到MySQL的COUNT(*)的效率,发现越说越说不清楚,干脆写下来,分享给大家. COUNT(*)与COUNT(COL)网上搜索了下,发现各种说法都有:比如认为COUNT(COL)比COUNT(*)快的:认为COUNT(*)比COUNT(COL)快的:还有朋友很搞笑的说到这个其实是看人品的. 在不加WHERE限制条件的情况下,COUNT(*)与COUNT(COL)基本可以认为是等价的:但是在有WHERE限制条件的情况下,COUNT(*)会比COUNT(COL)快非常多: 具体的数据参考如下:

MySQL Order By Rand()效率【转载】

最近由于需要大概研究了一下MYSQL的随机抽取实现方法.举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1. 但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描.但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机. 但是真正测试一下

【转载】解析提高PHP执行效率的50个技巧

1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的”函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故 把函数加上了双引号). 2.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 3.$row['id'] 的速度是$row[id]的7倍. 4.echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而

转载:关于加班和效率

转帖:http://coolshell.cn/articles/10217.html 微博上看到了这么一个贴子,就像以前在<腾讯,竞争力 和 用户体验>中批评过腾讯说自己的核心竞争力是员工加班一样,我顺着Winter的回复也批评了一下这个微博—— “靠加班超越对手?!劳动密集型么?我要是对手的话,我就来趁机挖人了,直接摁死你……//@寒冬winter: 当一个管理者的智慧无法衡量一支团队的产出的时候,他就会把“工时”当做最后的救命稻草,死死抱住——这是他唯一听得懂的东西了.” 然后,@玄了个澄