How is the "switch" compiled?

The opcode switch

in CIL is quite limited compared to what C # offers. It accepts a single jump table containing a sequence of labels, where hopping if the argument is the index of the label. Thus, unlike C #, you can include a non-negative integer and only for all cases from 0 to n.

On the other hand, the C # switch can be used for strings and even negative numbers.

I've done some tests and it seems like simple ==

equality for strings , so switch

no faster than if

/ else if

in this case despite popular belief . ==

calls Equals

what an ordinal comparison (i.e. bytewise) does.

Also, if it seems that if the cases are "consistent enough", it is compiled with real opcode switch

. The compiler is even so smart that it finds the minimum of cases and subtracts that from the value, effectively making cases from 0.

If there are some cases outside of the sequential range, it turns them into a normal comparison, but keeps the switch. If there are spaces in the switch, they indicate the next instruction ( default:

).

So, I wonder what is the complete set of rules that the compiler takes into account when compiling an instruction switch

in C #? When does it decide to turn it into opcode switch

and when does it only convert to regular comparisons?

Edit: It looks like a lot of lines in switch

, it caches them statically Dictionary<string, int>

.

+3


source to share





All Articles