c - if 语句和 mod(SIZE) 之间的效率差异
问题描述
研究我发现使用(i+1)mod(SIZE)
来在元素数组中执行循环。所以我想知道这种方法是否比 if 语句更有效......
例如:
#define SIZE 15
int main(int argc, char *argv[]) {
int items[SIZE];
for(int i = 0; items[0] < 5; i = (i + 1) % SIZE) items[i] += 1;
return 0;
}
它比(?)更有效:
#define SIZE 15
int main(int argc, char *argv[]) {
int items[SIZE];
for(int i = 0; items[0] < 5; i++) {
if(i == SIZE) i = 0;
items[i] += 1;
}
return 0;
}
感谢您的回答和您的时间。
解决方案
您可以在线检查程序集(即此处)。结果取决于架构和优化,但如果没有优化并且对于带有 GCC 的 x64,您会得到此代码(作为一个简单示例)。
示例 1:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-68], edi
mov QWORD PTR [rbp-80], rsi
mov DWORD PTR [rbp-4], 0
.L3:
mov eax, DWORD PTR [rbp-64]
cmp eax, 4
jg .L2
mov eax, DWORD PTR [rbp-4]
cdqe
mov eax, DWORD PTR [rbp-64+rax*4]
lea edx, [rax+1]
mov eax, DWORD PTR [rbp-4]
cdqe
mov DWORD PTR [rbp-64+rax*4], edx
mov eax, DWORD PTR [rbp-4]
add eax, 1
movsx rdx, eax
imul rdx, rdx, -2004318071
shr rdx, 32
add edx, eax
mov ecx, edx
sar ecx, 3
cdq
sub ecx, edx
mov edx, ecx
mov DWORD PTR [rbp-4], edx
mov ecx, DWORD PTR [rbp-4]
mov edx, ecx
sal edx, 4
sub edx, ecx
sub eax, edx
mov DWORD PTR [rbp-4], eax
jmp .L3
.L2:
mov eax, 0
pop rbp
ret
示例 2:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-68], edi
mov QWORD PTR [rbp-80], rsi
mov DWORD PTR [rbp-4], 0
.L4:
mov eax, DWORD PTR [rbp-64]
cmp eax, 4
jg .L2
cmp DWORD PTR [rbp-4], 15
jne .L3
mov DWORD PTR [rbp-4], 0
.L3:
mov eax, DWORD PTR [rbp-4]
cdqe
mov eax, DWORD PTR [rbp-64+rax*4]
lea edx, [rax+1]
mov eax, DWORD PTR [rbp-4]
cdqe
mov DWORD PTR [rbp-64+rax*4], edx
add DWORD PTR [rbp-4], 1
jmp .L4
.L2:
mov eax, 0
pop rbp
ret
你看,对于 x86 的特定情况,没有模数的解决方案要短得多。
推荐阅读
- python - 将包含元组的 DataFrame 列转换为行
- evernote - SDK Evernote PHP - 仅在给定堆栈中搜索笔记
- flutter - 引发了另一个异常:“MyApp”类型不是“StatelessWidget”类型的子类型
- xcode - 无法在 Xcode 中为 iPhone 4s 模拟器构建 Flutter 应用程序
- python - 相对导入抛出 ValueError
- macos - 一种在 VS Code C# 中为#regions 着色的方法
- reactjs - 单击卡片,然后导航到反应中的卡片页面详细信息
- sql-server-2008 - 附加 mdf 文件时出现 SQL Server 版本错误
- pytorch - Pytorch DataLoader - 选择类 STL10 数据集
- ruby-on-rails - 基于主题创建视图的最佳方式