Do local vars help the C# compiler, or will it assume invariance?

I got into coding at a time when compilers weren’t too bright, so when I’m programming in Unity C# I will often write code specifically designed to anticipate what the compiler will do, and to make it generate something more efficient.

So rather than write this code, which references the same values multiple times:

if ((int)Layer.EnemyShot == c.gameObject.layer || (int)Layer.Enemy == c.gameObject.layer) {
  ExplodeShip();
  if ((int)Layer.EnemyShot == c.gameObject.layer) game.ScorePoints(25, false);
}

I will write the following, which encourages the compiler to use registers for storage:

int l = c.gameObject.layer;
bool isEnemyShot = (int)Layer.EnemyShot == l;
if (isEnemyShot || (int)Layer.Enemy == l) {
  ExplodeShip();
  if (isEnemyShot) game.ScorePoints(25, false);
}

But is the Unity C# compiler actually smart enough to perform these optimizations on my behalf, with the assumption that these values won’t change within a single game loop?

The answer is clearly: No (it doesn’t assume invariance). What you suggest would require that the compiler has knowledge of the purpose of a method and what it exactly does. That’s not the purpose of a compiler. Code optimisations by the compiler are purely based on syntax, logic and what the target system allows.

In your example code “.gameObject” is a method. The compiler can’t assume that the returned value will be the same for both calls. Same for “.layer” which is a property as well. Of course UT could implement such “hardcoded” optimisations, but it’s not as easy as it sounds. Unity uses the C# Mono compiler and i’m pretty sure that they didn’t change much if they even have. Keep in mind you can compile your whole code with the normal C# .NET compiler and just place the compiled assembly in your project.

ps: The C# compiler doesn’t compile the C# code to machine code but to an intermediate language, the CIL (common intermediate language) which is stack based and doesn’t have registers. It’s up to the executing CLR to compile the CIL to machine code. How the final code looks like might vary heavily depending on the target device (PC 32 / 64 bit, Android, iOS, PlayStation, Wii, …)

I did not start coding in a time that compilers weren’t too bright. However, intrinsically I have always assumed that if a value has to be retrieved by a layered process(reference another class and then grab it’s variable) then it takes more steps to get the value. Thus, if this value is going to be referenced multiple times in a block of code, I straightway assign it to a local variable first.

But I don’t know the innards of the unity compiler.