16

There are often times when you know for a fact that your loop will never run more than x number of times where x can be represented by byte or a short, basically a datatype smaller than int.

Why do we use int which takes up 32 bits (with most languages) when something like a byte would suffice which is only 8 bits.

I know we have 32 bit and 64 bit processes so we can easily fetch the value in a single trip but it still does consume more memory. Or what am I missing here?

UPDATE: Just to clarify. I am aware that speed wise there is no difference. I am asking about the impact on memory consumption.

crennie
  • 674
  • 7
  • 18
uriDium
  • 13,110
  • 20
  • 78
  • 138
  • Really? Most code I've seen uses some form of unsigned type. – Billy ONeal Nov 17 '10 at 14:37
  • 1
    @Billy ONeal: On some embedded micros, an unsigned type may offer better performance than a signed one, at the expense of requiring greater care with loop termination logic. On the other hand, if a processor like an ARM stores something like a uint16 in a 32-bit register, it must add extra code to 'clip' the value to 16 bits. No such code would be needed with an int16 (since anything is allowed to happen when an int16 is assigned a value outside the -32768..32767 range, a compiler could just let its value do whatever's convenient). – supercat Nov 17 '10 at 17:31
  • 2
    Are you creating enough loop counters to where changing their types has a *visible* effect on memory consumption? If so, then I submit you have bigger problems than just using a wider-than-necessary type. – John Bode Nov 17 '10 at 17:31
  • @supercat: I'm not saying unsigned is better -- they're going to have the same effects on most machines. However, in most languages of which I am aware, any standard kind of container returns size or length as an unsigned type, and trying to use an `int` in such loops results in compiler warnings. (Because of the signed/unsigned mismatch in the comparison) – Billy ONeal Nov 17 '10 at 18:06
  • @John Bode. No not at all. I just wanted some education. Every now and then I question why do we do something in such a way. – uriDium Nov 18 '10 at 12:58

6 Answers6

28

In C, an "int" is defined as the most efficient integer type for the current machine.

It usually match the registers of the CPU, that's how it is the most eficient.

Using a smaller type of integer value may result in some bit-shifting or bit masking at the CPU level so you would get no gain...

siukurnin
  • 2,862
  • 17
  • 20
  • 11
    Actually, it's defined as the "natural word size", which may or may not be the most efficient type. For the most efficient type, use C99's fastint_t. – Billy ONeal Nov 17 '10 at 14:34
  • 1
    Something about demystifying these details about programming is actually really exciting – sova Nov 17 '10 at 18:39
  • I was more asking about memory consumption. – uriDium Nov 19 '10 at 10:35
  • 1
    memory consumption ? see larsmans answer : usually your loop counter is in a register unfrequently in memory. and anyway alignment issues may cause your variable to use more than you think. – siukurnin Nov 23 '10 at 10:40
8

Accessing an integer size that is the same size as the native word size is going to be the most efficient. Using a byte will almost certainly require as much space as the native word size and require shifting and masking to access, so there is nothing to gain.

In practical terms, unless you have a very, very large loop or severe timing restrictions, it isn't going to make much difference.

But as always, use whatever is most readable, and benchmark/profile first...

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • I highly doubt that an optimizing compiler wouldn't simply allocate an `int` of space for that `char` if in fact the `int` was more efficient. OTOH, on most architectures of which I am aware there's no difference in speed between an `int` and a `char`. – Billy ONeal Nov 17 '10 at 14:35
7

I almost always use int unless there is a very good reason not to, just because everyone always uses it. This is to avoid the next developer having to spend time thinking Why didn't he use an int here, is there some special reason I need to know about.

The more standard my code is, the easier it is to read in the future.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
6

In many cases, the loop counter consumes exactly one processor register. Changing the type to an 8- or 16-bit integer doesn't change that, as the registers have fixed size (32 bits on a 32-bit platform, etc.).

Sometimes, the loop counter may be placed in RAM, e.g. when you are calling a function from the loop. Then, yes, you may be wasting a few bytes, but generally not enough to be worried about. Storing and loading the loop counter may in fact be slower when using something different from an int.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
4

In terms of the Java Language Specification there is an interesting point to note about the use of long and double:

For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64 bit value from one write, and the second 32 bits from another write. Writes and reads of volatile long and double values are always atomic. Writes to and reads of references are always atomic, regardless of whether they are implemented as 32 or 64 bit values. VM implementors are encouraged to avoid splitting their 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.

Clearly this makes using a long or double in your looping variable less efficient than an int in the Java memory model, but implementations may vary in performance.

Gary
  • 7,167
  • 3
  • 38
  • 57
0

I'm tempted to add something here even if it's a very old thread. I don't fully agree with "I am aware that speed wise there is no difference". Indeed, very often in for loop there is array indexing such as in

for (i=0; i<len; i++) s = A[i]

Then, even if your array is of size less that 128, you will see a notable speed difference whether i is an int or a byte. Indeed, to perform pointer arithmetic in A[i] the processor has to convert your integer into something which has the same size as a pointer. If the integer already has the same size, then there is no conversion which induce faster code. On a 64 bits machine, I've seem 20% speedup on programs by using long int for loop indexes on very small array instead of char (C/C++ programs).

hivert
  • 10,579
  • 3
  • 31
  • 56