Better Practice: Size of Integers

Arokh

Centurion
Joined
Apr 11, 2006
Messages
124
If been wondering about it some time now:

If you know the range of a variable,
is it more appropiate to set it to the respective Integer?
Lets say we have:
0 - 100 - Byte
0 - 30000 UInt16
etc.

Or should I just stick to the default Integer 2^32?

I've tested a bit and working with smaller Integers is a bit faster,
but only if you don't have to convert between them.
Which happens often since most classes like List(Of T), ArrayList, etc. work with Int32.

I know that regardless of what type I take the speed difference is neglectable,
at least in the program I'm currently writing,
but maybe there is a rule of thumb for something like that.
 
Integer for single variables, correct size for data blocks

For individual variables I would suggest using Integer unless they are passed to methods which expect smaller data types. If storing large quantities of data then it makes sense to use the most appropriately sized type. For example, using any type larger than Byte to store the byte data from a file would just be wasteful.

You've mentioned List(Of T) and ArrayList. If you are storing the Count property for instance, you may as well use Integer. If you are talking about the data actually stored in the list, use the appropriate data type.

Also, I would advise against using unsigned data types unless you have a specific need for them. The number 30000 can be represented by a regular signed Short, there is no reason to use the unsigned equivalent.
 
Re: Integer for single variables, correct size for data blocks

Here's my two cents, though it amounts to about the same thing as MrPaul's.

There are some different considerations in terms of performance. Copying arrays of bytes will be faster than copying arrays of integers since they are one fourth the size, but most arithmatic operations are performed as integers and you will see very similar execution speed. Even if you add two short integers or two bytes, the processor still uses 32-bit operations and the extra bits are simply truncated after the overflow check.

When you are working with a structure, depending on how members are packed, smaller data types might even perform worse than a full Int32. If four bytes are packed into a single 32-bit word, I would imagine it would take a little longer to retrieve or store a value into one of these members.

In terms of memory, the real question is whether you need to conserve the bytes. Unless you are creating a very large number of objects or large arrays, you would probably never know the difference. If the integer is a member of a structure, the amount of memory you save would depend on how the data is laid out. Structures are padded to fill out 32-bit boundaries. And if the integer is a member of a class it is likely to be padded. Classes aren't intended to be binary creatures like structures, and I would guess that the jit-compiler would use 32 bits for any member 32-bits or smaller.

As far a local variables go, they reside on the stack, so I really wouldn't worry about saving memory. Use what's simplest.

If I had to give a one sentence answer, I would say don't bother using smaller integers unless you are in need of a memory optimization.
 
Thanks for all your input.
I'll keep my Integers to the 2^32 one since memory isn't really an issue.
 
What about 64 bit processors?

Does anyone know how fixing the size of your integers affects application performance when running on 32 bit versus 64 bit processors? How can the JIT compiler help keep everything running as efficiently as possible?

My intuition tells me that the more flexibility you give the compiler in this case, the more efficient your software will be when moving between processor types. It's one of the huge advantages of managed code.
 
Re: What about 64 bit processors?

I believe that MSIL supports a native-sized integer, but no languages that I know of support this; it is, by definition, inconsistent.

Like I said before, integers smaller than native size should perform equally with arithmatic operations and faster when copying arrays. The JIT compiler manages the packing and padding for you. The only real difference I would expect to see in terms of integer size versus performance is that 64-bit integers won't be slow anymore.

I don't quite get your meaning when you talk about giving the compiler flexibility. Flexibility in our code? Or flexibility programmed into the compiler by Microsoft?
 
Re: What about 64 bit processors?

I don't quite get your meaning when you talk about giving the compiler flexibility. Flexibility in our code? Or flexibility programmed into the compiler by Microsoft?
I was thinking in our code. You should get native word sizes for free if you use the proper level of abstraction and let the compiler decide what's best for the application.

If you declare your ints to be 32 bits, they will always be 32 bits even if you're on a 64 bit processor. If you declare your ints to be Integers, the compiler can figure everything out and you don't have to worry about changing your code. I thought this is what managed code was supposed to be all about.
 
Re: What about 64 bit processors?

I thought this is what managed code was supposed to be all about.
It's an important aspect of managed code, but (and correct me if I'm wrong) doesn't a C# int or VB Integer turn into a System.Int32 when compiled?
 
Re: What about 64 bit processors?

doesn't a C# int or VB Integer turn into a System.Int32 when compiled?
That's my point exactly. Shouldn't the size of an Integer depend on the Architecture for which it is compiled?

I could be making wrong assumptions thinking that .Net works similarly to Linux with regards to support on 64 bit architectures, though. I'm not really sure what happens to a C# int after compilation on different architectures.
 
Re: What about 64 bit processors?

I checked and the CLR does support a "natural integer" (native) type, with opcodes for built-in support, but with my C# Express 2008 set to compile for "Any CPU," the result is Int32--explicitly 32 bits. I haven't tried compiling for 64-bit, but I'm guessing that you will see the same result: 32 bits. I think Microsoft would prefer that an int is always the same thing, no matter which processor you use, because a lot of code depends on an int being 32-bits. It would be nice if C# or VB supported a native integer as well, though. I'd have no problem declaring my variables a nints.
 
Back
Top