Outside of the ensuring that they cannot be changed (to the tune of a compiler error), does the JIT make any optimisations for const locals?
Eg.
public static int Main(string[] args) { const int timesToLoop = 50; for (int i=0; i<timesToLoop; i++) { // ... } }
No, const does not help the compiler make faster code. Const is for const-correctness, not optimizations.
Constants can make your program more readable. For example, you can declare: Const PI = 3.141592654. Then, within the body of your program, you can make calculations that have something to do with a circle. Constants can make your program more readable.
o Constants make our programs easier to read by replacing magic numbers and strings with readable names whose values are easy to understand. o Constants make our program easier to modify. o Constants make it easier to avoid mistakes in our programs.
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.
The generated IL is different (using Release mode):
using constant local using normal local --------------------------------------------------------------------- .entrypoint .entrypoint .maxstack 2 .maxstack 2 .locals init ( .locals init ( [0] int32 i) [0] int32 timesToLoop, L_0000: ldc.i4.0 [1] int32 i) L_0001: stloc.0 L_0000: ldc.i4.s 50 L_0002: br.s L_0008 L_0002: stloc.0 L_0004: ldloc.0 L_0003: ldc.i4.0 L_0005: ldc.i4.1 L_0004: stloc.1 L_0006: add L_0005: br.s L_000b L_0007: stloc.0 L_0007: ldloc.1 L_0008: ldloc.0 L_0008: ldc.i4.1 L_0009: ldc.i4.s 50 L_0009: add L_000b: blt.s L_0004 L_000a: stloc.1 L_000d: ret L_000b: ldloc.1 L_000c: ldloc.0 L_000d: blt.s L_0007 L_000f: ret
As you can see the compiler replaces all variable usages by the value of the constant which results in a smaller stack.
I gave the code a quick performance test, using Snippet Compiler. The code I used is as follows:
public static void Main() { DateTime datStart = DateTime.UtcNow; const int timesToLoop = 1000000; for (int i=0; i < timesToLoop; i++) { WL("Line Number " + i.ToString()); } DateTime datEnd = DateTime.UtcNow; TimeSpan tsTimeTaken = datEnd - datStart; WL("Time Taken: " + tsTimeTaken.TotalSeconds); RL(); }
Note, WL and RL are simply helper methods to read and write to the console.
To test the non-constant version, I simply removed the const
keyword. The results were surprising:
Time Taken (average of 3 runs) Using const keyword 26.340s Without const keyword 28.276s
I'm aware that this is very rough'n'ready test, but the use of the const
keyword appears to count as a valid micro-optimization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With