什么样的代码会被编译器优化

描述

现在的编译器有多智能,可能你辛辛苦苦写的代码,在编译器看来就是几句废话,直接被删除掉。

以 gcc 编译器为例,编译的时候可以加上 -O 选项来优化代码,优化等级从 0 到 3。

写一些简单的代码给大家演示下。

 

#include 


void delay()
{
    for (int i = 0; i < 40000; i++)
        for (int j = 0; j < 10000; j++);
}


int main()
{
    printf("helloworld
");


    delay();


    printf("helloworld
");
    
    return 0;
}

 

比如在两条输出语句之间加上延时,正常的现象是这样的,很明显,延时函数起了作用。

如果编译的时候加上 O1 优化选项,在编译器看来,delay 函数什么事都没干,可以直接删掉。

比较两者的汇编代码,就能看出开启 O1 优化后,主函数中没有调用 delay,运行的现象也确实没有延时。

再比如这样的代码,test 函数直接返回了 1234。

如果不开启优化,主函数会调用 test 函数,如果开启了优化,编译器会跳过调用 test 函数,直接取他的返回值来使用。

再来看下 O2 优化级别,比如这个代码:

 

#include 


void test()
{
    printf("helloworld
");
}


int main()
{
    for (int i = 0; i < 3; i++)
    {   
        test();
    }   


    return 0;
}

 

循环调用 test 函数,test 函数也只是简单的使用 printf 输出字符串。

三份汇编代码分别对应三个不同的优化级别,没开优化,O1 优化,O2 优化。

没开优化的时候,汇编代码就是对应 C 代码,有循环,循环中调用 test 函数。

开启 O1 优化,循环没了,直接调用三次 test 函数,因为循环确实浪费时间。

开启 O2 优化,这次直接把 test 函数跳过,主函数中直接调用 puts 函数,这里的 puts ,就是 printf 优化而来,前面讲过,使用 printf 直接输出字符串,编译器会默认优化成 puts。

最后还有一个级别是 O3,O3 在 O2 的基础上优化更深。不过关于 O3 的优化并没有找到简短的代码,这里就不给大家做演示。

在平时的学习中并不建议使用编译器的优化策略,尤其是更高级别的优化,为了提升代码的运行效率,很多时候编译器会调整代码结构,导致运行的结果跟我们预期不一样。作为初学者,知道有这么回事就行。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分