在..中使用short而不是int的好处.环
Benefit of using short instead of int in for... loop
在for循环中使用short而不是int有什么好处吗?即
for(short j = 0; j < 5; j++) {
99%的循环涉及3000以下的数字,所以我认为int是浪费字节。谢谢
不,没有任何好处。总之,short可能会占用一个完整的寄存器(32位,一个int)。
在IDE中输入额外的两个字母也会浪费几个小时。(那是个笑话)。
否。循环变量可能会被分配给一个寄存器,因此它最终会占用相同的空间。
查看生成的汇编代码,您可能会发现使用int
会生成更干净的代码。
c代码:
#include <stdio.h>
int main(void) {
int j;
for(j = 0; j < 5; j++) {
printf("%d", j);
}
}
使用缩写:
080483c4 <main>:
80483c4: 55 push %ebp
80483c5: 89 e5 mov %esp,%ebp
80483c7: 83 e4 f0 and $0xfffffff0,%esp
80483ca: 83 ec 20 sub $0x20,%esp
80483cd: 66 c7 44 24 1e 00 00 movw $0x0,0x1e(%esp)
80483d4: eb 1c jmp 80483f2 <main+0x2e>
80483d6: 0f bf 54 24 1e movswl 0x1e(%esp),%edx
80483db: b8 c0 84 04 08 mov $0x80484c0,%eax
80483e0: 89 54 24 04 mov %edx,0x4(%esp)
80483e4: 89 04 24 mov %eax,(%esp)
80483e7: e8 08 ff ff ff call 80482f4 <printf@plt>
80483ec: 66 83 44 24 1e 01 addw $0x1,0x1e(%esp)
80483f2: 66 83 7c 24 1e 04 cmpw $0x4,0x1e(%esp)
80483f8: 7e dc jle 80483d6 <main+0x12>
80483fa: c9 leave
80483fb: c3 ret
使用int:
080483c4 <main>:
80483c4: 55 push %ebp
80483c5: 89 e5 mov %esp,%ebp
80483c7: 83 e4 f0 and $0xfffffff0,%esp
80483ca: 83 ec 20 sub $0x20,%esp
80483cd: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp)
80483d4: 00
80483d5: eb 1a jmp 80483f1 <main+0x2d>
80483d7: b8 c0 84 04 08 mov $0x80484c0,%eax
80483dc: 8b 54 24 1c mov 0x1c(%esp),%edx
80483e0: 89 54 24 04 mov %edx,0x4(%esp)
80483e4: 89 04 24 mov %eax,(%esp)
80483e7: e8 08 ff ff ff call 80482f4 <printf@plt>
80483ec: 83 44 24 1c 01 addl $0x1,0x1c(%esp)
80483f1: 83 7c 24 1c 04 cmpl $0x4,0x1c(%esp)
80483f6: 7e df jle 80483d7 <main+0x13>
80483f8: c9 leave
80483f9: c3 ret
通常情况下,当有人没有注意到(或忘记)这是一个狭窄的数据类型时,尝试为此进行优化只会加剧错误。例如,看看我研究过的这个bcrypt问题。。。非常典型:
BCrypt说类似的长密码是等价的——我、宝石还是密码学领域的问题?
然而问题仍然存在,因为int
也是有限大小的。最好花时间确保您的程序是正确的,并且不会因数字下溢和溢出而造成危险或安全问题。
如果你还没有遇到过的话,我在这里谈论的一些w/numeric_limits
可能是有信息的或有趣的:
http://hostilefork.com/2009/03/31/modern_cpp_or_modern_art/
没有。无论如何,您的计数器很可能最终会出现在寄存器中,并且它们通常至少与int 大小相同
我认为没有太大区别。编译器可能会为计数器变量使用整个32位寄存器(在32位模式下)。在最坏的情况下(当不使用寄存器时),您最多只会浪费堆栈中的两个字节
如果循环索引永远不会为负,则作为循环计数器的int
的一个潜在改进是unsigned int
(或适用的std::size_t
)。在大多数编译器中,使用short
而不是int
并没有什么区别,下面是我的编译器。
代码:
volatile int n;
int main()
{
for(short j = 0; j < 50; j++) // replaced with int in test2
n = j;
}
g++4.5.2-march=x86_64 linux 上的本机-O3
// using short j // using int j
.L2: .L2:
movl %eax, n(%rip) movl %eax, n(%rip)
incl %eax incl %eax
cmpl $50, %eax cmpl $50, %eax
jne .L2 jne .L2
clang++2.9-march=x86_64 linux 上的本机-O3
// using short j // using int j
.LBB0_1: .LBB0_1:
movl %eax, n(%rip) movl %eax, n(%rip)
incl %eax incl %eax
cmpl $50, %eax cmpl $50, %eax
jne .LBB0_1 jne .LBB0_1
英特尔C++11.1-在x86_64 linux 上快速
// using short j // using int j
..B1.2: ..B1.2:
movl %eax, n(%rip) movl %eax, n(%rip)
incl %edx incl %eax
movswq %dx, %rax cmpl $50, %eax
cmpl $50, %eax jl ..B1.2
jl ..B1.2
sparc 上的Sun C++5.8-xO5
// using short j // using int j
.L900000105: .L900000105:
st %o4,[%o5+%lo(n)] st %o4,[%o5+%lo(n)]
add %o4,1,%o4 add %o4,1,%o4
cmp %o4,49 cmp %o4,49
ble,pt %icc,.L900000105 ble,pt %icc,.L900000105
因此,在我拥有的四个编译器中,只有一个编译器的结果有任何差异,而且,在int的情况下,它实际上使用了更少的字节。
正如大多数其他人所说,在计算上没有优势,可能会更糟。然而,如果循环变量用于需要短路的计算,那么它可能是合理的:
for(short j = 0; j < 5; j++)
{
// void myfunc(short arg1);
myfunc(j);
}
真正所做的只是防止出现警告消息,因为传递的值将被提升为int(取决于编译器、平台和C++方言)。但它看起来更干净,IMHO。
当然不值得纠缠。如果你想优化,请记住规则(忘记是谁想出的):
- 不要
- 步骤1,第一个措施失败
- 做出改变
- 如果无聊,退出,否则转到步骤2
- 'short int'持有的值溢出,但"自动"不会溢出?
- 从“ int”到'int16_t {aka short int}'内部{}的“((int)a) -1)”的缩小转换
- 如果超过 short int(c++) 的最大值会发生什么
- C++ 中有符号 int 和无符号 short 的比较
- Short Int基掩码在C 库子弹中的工作方式
- 为什么C/C++会自动将char/wchar_t/short/bool/enum类型转换为int
- 为什么编译器将"char"与"int"匹配而不是"short"?
- 为什么 foo(short int *) 和 bar(signed short *) 认为 QT 的签名不同
- 错误:从 'short unsigned int*' 到"短无符号 int"的转换无效|(在 C++ 中)
- wchar_t*到short int的转换
- 将无符号short/int强制转换为char*
- 像javashort[]一样在c中创建short int数组
- C/C++:在32位机器上的sizeof(short)、sizeof(int)、sizeof(long)、size of
- 对'icu_56::UnicodeString::UnicodeString(signed char, unsigned short const*, int)' 的未定义引用
- 将无符号字符转换为 int 和 short
- gcc 奇怪的转换警告(<B>从"int"转换为"A::count_type {aka short unsigned int}"可能会改变其值)
- 对类中的整数成员变量使用short、int或long
- 让template通过指定bitsize在char/short/int之间进行选择
- 是实现定义的unsigned short + int类型
- 为什么在C和c++中进行算术运算之前必须将short类型转换为int类型?