Search code examples
c#.netilopcode

What's the purpose of the 'short' notation of IL?


Every time I bumb into them in IL: br_S, ldc_i4_S, ldarg_S, etc, etc... So I just have to ask the question:

I mean... If you're JIT'ing a language from IL to native assembler, it shouldn't really matter in terms of performance, right? So what's the purpose of having these 'short-hand' notations? Is it just for having fewer bytes in the IL binaries (e.g. as a compression mechanism) or is there some other reason?

And if it's just as a compression mechanism, why not use a compression algorithm like deflate?


Solution

  • Sure, it is a micro-optimization. But the Golden Rule of micro-optimizing applies strongly here, they turn macro when you can apply the optimization over and over again. Which is certainly the case here, method bodies are small so the vast majority of branches are short ones, methods have a limited number of arguments and local variables so a single byte is enough to address them, the constants 0 through 9 very often appear in a real program.

    Add them all up and you have a macro-optimization on a large assembly, many kilobytes shaved-off. Which does matter at runtime, that's IL that doesn't have to page-faulted into RAM. Warm-start time in a jitted program is always an issue and has been attacked from every possible angle.

    In general, the .NET Framework is relentlessly micro-optimized. Largely because Microsoft just can't assume that their code won't be on the critical path in a program.