Take the 2-minute tour ×

I have a questionable coding practice.

When I need to iterate through a small list of items whose count limit is under 32000, I use Int16 for my i variable type instead of Integer. I do this because I assume using the int16 is more efficient than a full blown Integer.

Am I wrong? Is there no effective performance difference (however minute) between using an Int16 vs an Integer? Should I stop using Int16 and just stick with Integer for all my counting/iteration needs? (VB OR C#)

Thanks in advance for any guidance!

share|improve this question

10 Answers 10

up vote 36 down vote accepted

According to the below reference, the runtime optimizes performance of Int32 and recommends them for counters and other frequently accessed operations.

From the book: MCTS Self-Paced Training Kit (Exam 70-536): Microsoft® .NET Framework 2.0—Application Development Foundation

Chapter 1: "Framework Fundamentals"
Lesson 1: "Using Value Types"

Best Practices: Optimizing performance with built-in types



Also, Table 1-1 in the same section lists recommended uses for each type. Relevant to this discussion:

  • Int16 - Interoperation and other specialized uses
  • Int32 - Whole numbers and counters
  • Int64 - Large whole numbers
share|improve this answer

You should almost always use Int32 or Int64 (and, no, you do not get credit by using UInt32 or UInt64) when looping over an array or collection by index.

The most obvious reason that it's less efficient is that all array and collection indexes found in the BCL take Int32s, so an implicit cast is always going to happen in code that tries to use Int16s as an index.

The less-obvious reason (and the reason that arrays take Int32 as an index) is that the CIL specification says that all operation-stack values are either Int32 or Int64. Every time you either load or store a value to any other integer type (Byte, SByte, UInt16, Int16, UInt32, or UInt64), there is an implicit conversion operation involved. Unsigned types have no penalty for loading, but for storing the value, this amounts to a truncation and a possible overflow check. For the signed types every load sign-extends, and every store sign-collapses (and has a possible overflow check).

The place that this is going to hurt you most is the loop itself, not the array accesses. For example take this innocent-looking loop:

for (short i = 0; i < 32000; i++) {

Looks good, right? Nope! You can basically ignore the initialization (short i = 0) since it only happens once, but the comparison (i<32000) and incrementing (i++) parts happen 32000 times. Here's some pesudo-code for what this thing looks like at the machine level:

  Int16 i = 0;
  Int32 temp0 = Convert_I16_To_I32(i); // !!!
  if (temp0 >= 32000) goto END;
  Int32 temp1 = Convert_I16_To_I32(i); // !!!
  Int32 temp2 = temp1 + 1;
  i = Convert_I32_To_I16(temp2); // !!!
  goto LOOP;

There are 3 conversions in there that are run 32000 times. And they could have been completely avoided by just using an Int32 or Int64.

Update: As I said in the comment, I have now, in fact written a blog post on this topic, .NET Integral Data Types And You

share|improve this answer
Excellent explanation. Shame yours didn't get accepted! –  Sean Hanley Oct 2 '08 at 16:23
Thanks, Yadyn. I've added this to my queue for things I should blog about when I actually start a blog. I've seen people make this mistake a lot in the past. –  Alex Lyman Oct 2 '08 at 17:26

Int16 may actually be less efficient because the x86 instructions for word access take up more space than the instructions for dword access. It will depend on what the JIT does. But no matter what, it's almost certainly not more efficient when used as the variable in an iteration.

share|improve this answer

The opposite is true.

32 (or 64) bit integers are faster than int16. In general the native datatype is the fastest one.

Int16 are nice if you want to make your data-structures as lean as possible. This saves space and may improve performance.

share|improve this answer

Use Int32 on 32-bit machines (or Int64 on 64-bit machines) for fastest performance. Use a smaller integer type if you're really concerned about the space it takes up (may be slower, though).

share|improve this answer

Any performance difference is going to be so tiny on modern hardware that for all intents and purposes it'll make no difference. Try writing a couple of test harnesses and run them both a few hundred times, take the average loop completion times, and you'll see what I mean.

It might make sense from a storage perspective if you have very limited resources - embedded systems with a tiny stack, wire protocols designed for slow networks (e.g. GPRS etc), and so on.

share|improve this answer

Never assume efficiency.

What is or isn't more efficient will vary from compiler to compiler and platform to platform. Unless you actually tested this, there is no way to tell whether int16 or int is more efficient.

I would just stick with ints unless you come across a proven performance problem that using int16 fixes.

share|improve this answer
He's asking for .net, so the platform is very well defined. –  Nils Pipenbrinck Sep 24 '08 at 18:51

I can't imagine there being any significant performance gain on Int16 vs. int.

You save some bits in the variable declaration.

And definitely not worth the hassle when the specs change and whatever you are counting can go above 32767 now and you discover that when your application starts throwing exceptions...

share|improve this answer

There is no significant performance gain in using a data type smaller than Int32, in fact, i read somewhere that using Int32 will be faster than Int16 because of memory allocation

share|improve this answer

The others here are correct, only use less than Int32 (for 32-bit code)/Int64 (for 64-bit code) if you need it for extreme storage requirements, or for another level of enforcement on a business object field (you should still have propery level validation in this case, of course).

And in general, don't worry about efficiency until there is a performance problem. And in that case, profile it. And if guess & checking with both ways while profiling doesn't help you enough, check the IL code.

Good question though. You're learning more about how the compiler does it's thing. If you want to learn to program more efficiently, learning the basics of IL and how the C#/VB compilers do their job would be a great idea.

share|improve this answer

Your Answer


