善于跟编译器学写代码

  • 我如何学习写代码

一直以来我都是从基础书本,从开源代码,从同事批评,从谷歌中改进自己”写代码”的技能.这里说的”写代码”,不是指具体的功能实现 函数调用,而是指一种编码习惯,例如命名习惯,留空习惯,注释习惯,等等在日常”写代码”中息息相关的片段.迄今为止我看过的没有那一本书(除了声名显赫的 code complete)教过我如何 跳出特定编程语言去写代码.这可能是我需要不断修炼的技能(去除特定的语法,语言,IDE,系统,最后程序员还剩下的东西 我估计那就是这里说的技能了.

  • 编译器如何写代码

今天我发现了一直伴随我身边的伙伴 – “编译器”,写代码技术已经是修炼到登峰造极的地步了,他给我的感觉 无异于 少林寺的扫地僧,首先看一段代码

// C/C++
int for1(int n)
{
    int i = 0;
    int s = 0;
    for(i = 0;i<n;i++)
    {
        s += i*2;
    }
    return s;
}


我设想它最后会被编译成如下代码

//参数判断
CMP R0,#0 
BLE LOC_CD4
//R0为函数传入参数
MOV R2,R0
//初始化局部变量
MOV R3,#0
MOV R0,R3
//for 循环开始
loc_CC0:
// i = i<em>2
MOV R3,R3,LSL#1
// s += i</em>2
ADD R0,R3
//i++
ADD R3,#1
CMP R3,R2
BNE loc_CC0
BX LR
loc_CD4:
MOV R0,#0
BX LR

但是实际是被编译成如下:

/参数判断
CMP     R0, #0
BLE     loc_CD4
//初始化局部变量
MOV     R3, #0
//编译器优化开始
//R2 = n*2
MOV     R2, R0,LSL#1
//初始化局部变量
MOV     R0, R3
loc_CC0:
//s += i 没错.没有乘2
ADD     R0, R0, R3
//这里实现乘2
ADD     R3, R3, #2
CMP     R3, R2
BNE     loc_CC0
BX      LR
loc_CD4: 
MOV     R0, #0
BX      LR

显然编译器在编译优化阶段 对for1函数进行的优化.在循环中减少了乘以2一句代码.
如果这个for循环次数非常多的话 这个优化是非常明显的.
我们根据编译器的优化 在写代码的时候可以把for1函数改进成如下:

int for3(int n)
{
    int i = 0;
    int s = 0;
    n *= 2;
    for(i = 0;i<n;i += 2)
    {
        s += i;
    }
    return s;
}

这个优化虽然不太明显.但是在运行代码的行数来说 减少了(n – 1)行.
而我们知道 程序每执行一句代码,其实是需要时间的.

3 评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注