Will the compiler be optimized for logical purpose?

This is what I want to do:

if(ABoolean || (BBoolean && CBoolean)) { SomeButton.Enabled = true; AnotherButton.Enabled = true; } else { SomeButton.Enabled = false; AnotherButton.Enabled = false; } 

I can switch it to:

 SomeButton.Enabled = (ABoolean || (BBoolean && CBoolean)); AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean)); 

For more concise code. My question is, the compiler optimizes the assignment so that it sees that the logical expression is the same, and assign its value to the second button, or it will calculate the value each time.

Note. I understand that this is a trivial example and that acceleration / deceleration will be negligible in terms of non-materiality, but it will help me better understand compiler optimization.

Edit: This is why I thought the second option could be optimized:

 class Program { static bool ABoolean = true, BBoolean = true, CBoolean = false; static bool AEnable, BEnable; static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 1000000000; i++) { Operation1(); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); Stopwatch sw1 = new Stopwatch(); sw1.Start(); for (int i = 0; i < 1000000000; i++) { Operation2(); } sw1.Stop(); Console.WriteLine(sw1.ElapsedMilliseconds); Console.Read(); } static void Operation1() { if (ABoolean || (BBoolean && CBoolean)) { AEnable = true; BEnable = true; } else { AEnable = false; BEnable = false; } } static void Operation2() { AEnable = (ABoolean || (BBoolean && CBoolean)); BEnable = (ABoolean || (BBoolean && CBoolean)); } } 

This led to an approximate difference of 8-9 seconds compared to 1 billion operations (the second option is faster). Since I added more β€œEnable” booleans, however, the second operation became slower.

+4
source share
3 answers

No, I would not expect the compiler to optimize this. Maybe JIT can optimize this (since it has more information), but I would not expect a C # compiler.

How could the compiler know if SomeButton.Enabled have a side effect that could change the value of ABoolean , BBoolean or CBoolean ?

EDIT: confirmation of this ... give the C # compiler an absolute probability:

 class Test { static void Main() { Foo(true, false, true); } static void Foo(bool x, bool y, bool z) { A = x || (y && z); B = x || (y && z); } static bool A { get; set; } static bool B { get; set; } } 

Compile with:

 csc /o+ /debug- Test.cs 

Code for Foo via ILDASM:

 .method private hidebysig static void Foo(bool x, bool y, bool z) cil managed { // Code size 37 (0x25) .maxstack 8 IL_0000: ldarg.0 IL_0001: brtrue.s IL_000c IL_0003: ldarg.1 IL_0004: brfalse.s IL_0009 IL_0006: ldarg.2 IL_0007: br.s IL_000d IL_0009: ldc.i4.0 IL_000a: br.s IL_000d IL_000c: ldc.i4.1 IL_000d: call void Test::set_A(bool) IL_0012: ldarg.0 IL_0013: brtrue.s IL_001e IL_0015: ldarg.1 IL_0016: brfalse.s IL_001b IL_0018: ldarg.2 IL_0019: br.s IL_001f IL_001b: ldc.i4.0 IL_001c: br.s IL_001f IL_001e: ldc.i4.1 IL_001f: call void Test::set_B(bool) IL_0024: ret } // end of method Test::Foo 

As you can see, the expression is really evaluated in both cases.

+7
source

The question is, the compiler optimizes the assignment so that it sees that the logical expression is the same, and assign its value to the second button, or it will calculate the value each time.

It will calculate the value every time.

What if it is a multi-threaded application. Some other thread can change it.

If they are not constant variables, they can be changed.

For optimization you can do

 SomeButton.Enabled = AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean)); 

In this case, it will be calculated once, and the value of AnotherButton and SomeButton is assigned first later. Remember his right to left in the assignment.

+4
source

No, the compiler will not optimize it in my experience, however you can do:

 SomeButton.Enabled = AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean)); 
+2
source

Source: https://habr.com/ru/post/1415603/


All Articles