编程珠玑第九章-代码优化 读书笔记

 

1、内存访问(连续内存访问与跨页面访问内存的区别)

注意在访问内存的时候,要注意内存的连续性,如果访问的内存不是连续的,那么程序的运行速度也会受到极大的影响

例如访问一个二维数组时,先访问行,再访问列,能够减少页面调度次数,同时cache命中率也相对高些。2、递归调用宏时,需要小心,宏中的某个参数被调用了多次以致数值发生了变化#define Max(a,b) ((a>b)?:(a):(b)) // Max(i++,j++),调用之后,i、j的值可能会增加两次

//max(i++,func(j++)),调用之后,可能会导致函数func()被调用两次

3. malloc可能花费很多的时间。对于经常需要分配的数据类型,可以建立缓存链表来提高速度。

实现代码如下:

#define NODESIZE 8
#define NODEGROUP 1000
int nodesleft = 0;
char *freenode;

void *pmalloc(int size)
{
    void *p;
    if (size != NODESIZE)
        return malloc(size);
    if (nodesleft == 0)
    {
        freenode = (char *)malloc(NODESIZE * NODEGROUP);
        nodesleft = NODEGROUP;
    }
    nodesleft--;
    p = (void *) freenode;
    freenode += NODESIZE;
    return p;
}

如果参数不等于NODESIZE,立即调用系统的malloc,当nodesleft为0时,另外分配一组节点。


4. 给定一个非常长的字节序列(假定有十亿),如何高效地统计1的个数呢?

第一种方法是计算每个输入单元(可能是一个8位的字符或者是32位的整数)中1的个数,然后将他们相加。为了找出16位整数中为1的个数,我们可以按顺序观察每一位,或者(使用类似b &= (b-1)的语句)对为1的位进行迭代,或者查表(例如查询一个2^16=65536的表)。

int OneCount(unsigned int x) 
{ 
  int count; 
  for(count=0; x>0; count++) 
    x&=x-1;//把最后面的1变0 
  return count; 
} 

const int idx[256]={0,1,1,……,8}//0~255中含1的个数 
int OneCount(unsigned int x) 
{ 
  int count=0; 
  for(; x>0; x>>=8) 
     count+=idx[x&255]; 
  return count; 
} 

第二种方法是计算输入中每个输入单元的个数,然后将该个数乘以相应输入单元中为1的位数,最后再对各个输入单元求总和。


5. 大多数的算术运算需要约为10纳秒的时间,但是除法和取模运算需要的运行时间接近100纳秒,所以
k=k%n; 可以替换为 if(k>=n) k=k-n;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值