The advantage of using short rather than int in for ... loop

Is there any use to using short instead of int in a for loop? i.e.

for(short j = 0; j < 5; j++) { 

99% of my loops include numbers below 3000, so I thought ints would be a waste of bytes. Thanks!

+6
source share
8 answers

Not. The loop variable is likely to be allocated to the register, so it will take up the same amount of free space.

+7
source

No, there is no benefit. In short, it will probably end up in any case a full register (which is 32 bits, int).

You’ll lose hours by typing the extra two letters in the IDE. (It was a joke).

+7
source

Look at the generated assembler code, and you will probably see that using int , cleaner code is generated.

C code:

 #include <stdio.h> int main(void) { int j; for(j = 0; j < 5; j++) { printf("%d", j); } } 

using short:

  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 

using 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 
+4
source

Most often, an attempt to optimize for this will only exacerbate errors when someone does not notice (or forgets) that this is a narrow data type. For example, check out this problem with bcrypt, which I studied ... quite typically:

BCrypt says long similar passwords are equivalent - is it a problem with me, a gem or a cryptography field?

However, the problem still exists, since int also finite. It is better to spend your time trying to make sure that your program is correct and does not create any dangers or security problems from numerical shortcomings and overflows.

Some of what I'm talking about w / numeric_limits may be informative or interesting if you have not come across this yet:

http://hostilefork.com/2009/03/31/modern_cpp_or_modern_art/

+3
source

Nope. Most likely, your counter will go into the register anyway, and they will usually be at least the same size as the int

0
source

I think there is not much difference. Your compiler will probably use the entire 32-bit register for the counter variable (in 32-bit mode). You will spend only two bytes from the stack, at most, in the worst case (when not using case)

0
source

One potential improvement over int as a loop counter is unsigned int (or std::size_t where applicable) if the loop index is never negative. Using short instead of int has nothing to do with most compilers, here are the ones I have.

the code:

 volatile int n; int main() { for(short j = 0; j < 50; j++) // replaced with int in test2 n = j; } 

g ++ 4.5.2 -march = native -O3 on x86_64 linux

 // 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 = native -O3 on x86_64 linux

 // 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 

Intel C ++ 11.1 -fast on 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 

Sun C ++ 5.8 -xO5 on sparc

 // 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 

So, of the four compilers that I have, only one even had any difference in the result, and in fact it used fewer bytes in the int case.

0
source

Like many others, there are no computational advantages and could be worse. However, if a loop variable is used in a calculation requiring a short one, then this may be warranted:

 for(short j = 0; j < 5; j++) { // void myfunc(short arg1); myfunc(j); } 

All this really prevents the warning, since the passed value will be passed to int (depending on the dialogs on the compiler, platform and C ++). But he looks cleaner, IMHO.

Of course, do not be obsessed. If you want to optimize, remember the rules (forget who came up with them):

  • Not
  • Failed to complete step 1, measure first
  • Make changes
  • If you are bored, exit and go to step 2.
0
source

Source: https://habr.com/ru/post/889984/


All Articles