One of these days, going through some code at work I noticed a colleague had made a for loop explicitly defining the iteration variable as a
short (which is an
Int16) instead of an
Int32) as usual (or in my case
var, which ends up being an
Something like the following, just for context:
After seeing this I thought, yeah, he's right, we should be more careful and use the types we really need. If we're iterating on a short range of values, why not use
short (or a even smaller type)? It may even have a (probably almost unnoticeable) gain in performance as we're saving memory right? Oh how wrong was I 😇
I began to wonder, why is it so unusual for us to see
shorts used in this context, and in the spirit of finding excuses for doing anything but what one's supposed to do, I went on searching for an answer (you can experience this massive search engine endeavor here).
I ended up in this MSDN question from 2006 that has answers for this.
It's a performance thing. A CPU works more efficient when the data with equals to the native CPU register width. This applies indirect to .NET code as well.
In most cases using int in a loop is more efficient than using short. My simple tests showed a performance gain of ~10% when using int.
Some more link clicking took me to Stack Overflow and this question with some more explanations if you're interested in checking it out.
Of course I wanted to check it out for myself and rolled a kind of stupid benchmark just for fun (using the awesome BenchmarkDotNet library).
I even added a
Int64) to the mix just to see the result, which was:
|ForUsingInt||9.601 us||0.1850 us||0.2594 us||1.00||0.00||0 B|
|ForUsingShort||17.963 us||0.3835 us||0.4565 us||1.87||0.07||0 B|
|ForUsingLong||9.112 us||0.2013 us||0.1977 us||0.95||0.03||0 B|
So, as expected given the previous explanations, the
int outperforms the
long keeps up with the
int (maybe because I'm on a 64 bit machine, so a
long is of native register size?). I would take this performance differences with a grain of salt, as in the real world we don't have an empty
for (hopefully), but yup, there is a difference.
If you want to take the benchmark and dig around a little more, you can get it from this repo.
NOTE: if I messed up on the benchmark by not taking something into consideration, please let me know.
Thanks for stopping by, cyaz!
PS: originally posted here