har*_*mas 57 c expression for-loop coding-style constantfolding
在许多编程比赛中,我看到有人写这种类型的for-loop
for(i = 0; i < (1 << 7); i++)
Run Code Online (Sandbox Code Playgroud)
除非我遗漏了什么,否则就是这样
for(i = 0; i < 128; i++)
Run Code Online (Sandbox Code Playgroud)
为何使用该(1 << 7)版本?
每次不必要的开销是不是计算条件?
oua*_*uah 76
是的,它们在行为上是等同的.
那为什么人们会使用(1 << 7)版本?
我想,他们用它来证明它是2的力量.
每次计算条件必须是开销!我无法找到这背后的原因!
不是真的,任何正常的编译器将取代1 << 7由128等两个环路将具有相同的性能.
(C11,6.6p2)"可以在翻译期间而不是运行时评估常量表达式,因此可以在常量可能的任何位置使用."
bar*_*nos 31
让我们将这些选项中的每一个翻译成简单的英语:
for(i = 0; i < (1 << 7); i++) // For every possible combination of 7 bits
for(i = 0; i < 128; i++) // For every number between 0 and 127
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,运行时行为应该相同.
实际上,假设一个不错的编译器,即使汇编代码也应该是相同的.
因此,第一个选项主要用于"发表声明".
您也可以使用第二个选项并在上面添加注释.
Yu *_*Hao 19
1 << 7是一个常量表达式,编译器将其视为128,运行时没有开销.
没有循环体,很难说为什么作者使用它.可能它是一个循环,迭代与7位相关的东西,但这只是我的猜测.
Sha*_*our 14
那为什么人们会使用(1 << 7)版本?
它是一种文档形式,它不是一个神奇的数字,但是2^7(两到七次幂)对于编写代码的人来说都是有意义的.现代优化编译器应该为这两个示例生成完全相同的代码,因此使用此表单没有任何成本,并且添加上下文有好处.
使用godbolt我们可以验证这一点确实是这样的,至少在几个版本gcc,clang和icc.使用带有副作用的简单示例来确保代码未完全优化:
#include <stdio.h>
void forLoopShift()
{
for(int i = 0; i < (1 << 7); i++)
{
printf("%d ", i ) ;
}
}
void forLoopNoShift()
{
for(int i = 0; i < 128; i++)
{
printf("%d ", i ) ;
}
}
Run Code Online (Sandbox Code Playgroud)
对于代码的相关部分,我们可以看到它们都生成以下内容直播:
cmpl $128, %ebx
Run Code Online (Sandbox Code Playgroud)
我们所拥有的是一个整数常量表达式,如草案C11标准部分中所定义的6.6 常量表达式所示:
整数常量表达式117)应具有整数类型,并且只能具有整数常量的操作数,枚举常量,字符常量,结果为整数常量的sizeof表达式,[...]
和:
常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.15)
我们可以看到在翻译期间允许评估常量表达式:
可以在转换期间而不是运行时期间评估常量表达式,并且因此可以在常量可以在任何地方使用.
for(i = 0; i <(1 << 7); i ++)
和
for(i = 0; i <128; i ++)
提供相同的性能,但开发人员可以在(i = 0; i <(1 << 7); i ++)在循环中使用的情况下获得巨大优势
for(int k = 0; k < 8; k++)
{
for(int i = 0; i < (1 << k); i++)
{
//your code
}
}
Run Code Online (Sandbox Code Playgroud)
现在它处于内循环上限,即(1 << k)随着2运行时的功率而变化.但如果您的算法需要此逻辑,则适用.
| 归档时间: |
|
| 查看次数: |
3909 次 |
| 最近记录: |