ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【学术】对于代码常系数影响因素的考察——以快读为例

2021-08-21 15:33:04  阅读:94  来源: 互联网

标签:汇编 ch 以快 ++ 读为例 int 系数 && inline


引子——快读

inline int read()
{
    char ch;int x=0;
    while((ch=getchar())<33);
    for(;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
    return x;
}

这段代码已经经过了一定程度的优化。比如为人熟知的 inline 关键字、使用 <33 判断空字符、压行等等。

但是,怎么知道它的具体优化效果呢?在这里,我们使用汇编的方式。

实验过程中的一些细节

  • 使用的编译器是 MinGW-w64 g++ 8.1.0;
  • 使用 C++11 标准;
  • 生成汇编代码的命令是 g++ -S test.cpp -o test.s

正文开始

首先,我们知道一些流传甚广的说法,接下来一一进行验证

我们用于测试的代码如下:

#include <cstdio>
inline int read()
{
    char ch;int x=0;
    while((ch=getchar())<33);
    for(;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
    return x;
}
int main()
{
    read();
    return 0;
}

1. 位运算 & 与逻辑运算 &&

这两者在布尔运算中运算结果完全等效,但是时间有差距。按照我们的一般认识,位运算是更快的。

但是,使用汇编验证后,得到的结果是:使用 && 时,汇编码长为 \(73\) 行;使用 & 时,汇编码长为 \(76\) 行!也就是说,&&& 速度上有微妙的差距。

那么,其它逻辑运算与位运算是否有类似的结果呢?

省略实验步骤,我得到的结论是:

  • ||| 完全等价;
  • !^1 要快许多。

2. inline 关键字

我们使用原本的测试代码进行实验,对比有无 inline 的汇编行数 (控制变量法)

结果令人意想不到:有 inline 时,汇编码长为 \(73\) 行;而无 inline 时,汇编码长为 \(70\) 行! 也就是说,inline 不一定可以优化常数


3. x=x*10+ch-'0' 的其它写法

想必你已经记住了不更改测试代码的情况下汇编有 \(73\) 行。

现在,我们把 x=x*10+ch-'0' 改为 x*=10,x+=ch-'0',看看汇编的变化。汇编代码变为了 \(69\) 行

但是经试验,将 x+=ch-'0' 再次拆开不会有任何变化。

其它与快读无关的更多研究


4. i++++i

曾有人说,++i 相比 i++ 有玄学优化,并给出了一堆理由。事实是否如此呢?

使用如下的测试代码:

int main()
{
    for(int i=1;i<=100;i++);
    return 0;
}

汇编结果很精简,只有 \(30\) 行。将其中的 i++ 改为 ++i 后,然而,结果长度并没有变化。所以说,在一般的循环语句中,i++++i 完全等价

但是有一些例外的情况。我们将代码添加一点东西:

int main()
{
    for(int i=1,j;i<=100;j=i++);
    return 0;
}

多了一条赋值语句。此时,汇编行数为 \(33\)。将其中的 i++ 改为 ++i 后,行数变为了 \(32\) 行。

虽然语义不等价,但这也说明了,在出现赋值的情况时,++ii++ 少一条汇编。


(仍会持续更新)

总结

所以,卡常要拒绝迷信,相信科学!

标签:汇编,ch,以快,++,读为例,int,系数,&&,inline
来源: https://www.cnblogs.com/ExplodingKonjac/p/15169674.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有