c# - Does IF perform better than IF-ELSE? -


which 1 of these blocks of code performs better, , 1 of them more readable? i'd guess gain negligible, particularly in second block. curious.

block #1

string height; string width; if (myflag == 1) {     height = "60%";     width = "60%"; } else {     height = "80%";     width = "80%"; } 

block #2

string height = "80%"; string width = "80%"; if (myflag == 1) {     height = "60%";     width = "60%"; } 

updated

the results when tested above code both blocks performed same

block #1

myflag = 1:   3 milliseconds myflag = 0:   3 milliseconds 

block #2

myflag = 1:   3 milliseconds myflag = 0:   3 milliseconds 

but 1 important thing noticed here(thanks matthew steeples answer here) since block of code have tested has not used variables height , width except assignment in if-else , if blocks of code block-1 , 2 respectively, the compiler has optimized il code removing if , if-else blocks in question showing invalid results our test here.

i have updated both code blocks write values of both height , width file using them again , forcing compiler run our test blocks(i hope), can observe code actual file writing part not effect our test results

this updated results, c# , il code

results

block #1

myflag = 1:   1688 milliseconds myflag = 0:   1664 milliseconds 

block #2

myflag = 1:   1700 milliseconds myflag = 0:   1677 milliseconds 

c#.net code

block #1

    public long withifandelse(int myflag)     {         stopwatch mytimer = new stopwatch();         string somestring = "";         mytimer.start();         (int = 0; < 1000000; i++)         {             string height;             string width;             if (myflag == 1)             {                 height = "60%";                 width = "60%";             }             else             {                 height = "80%";                 width = "80%";             }             somestring = "height: " + height + environment.newline + "width: " + width;         }         mytimer.stop();         file.writealltext("testifelse.txt", somestring);         return mytimer.elapsedmilliseconds;     } 

block #2

    public long withonlyif(int myflag)     {          stopwatch mytimer = new stopwatch();         string somestring = "";         mytimer.start();         (int = 0; < 1000000; i++)         {             string height = "80%";             string width = "80%";             if (myflag == 1)             {                 height = "60%";                 width = "60%";             }             somestring = "height: " + height + environment.newline + "width: " + width;         }         mytimer.stop();         file.writealltext("testif.txt", somestring);         return mytimer.elapsedmilliseconds;     } 

il code generated ildasm.exe

block #1

.method public hidebysig instance int64  withifandelse(int32 myflag) cil managed {   // code size       144 (0x90)   .maxstack  3   .locals init ([0] class [system]system.diagnostics.stopwatch mytimer,            [1] string somestring,            [2] int32 i,            [3] string height,            [4] string width,            [5] string[] cs$0$0000)   il_0000:  newobj     instance void [system]system.diagnostics.stopwatch::.ctor()   il_0005:  stloc.0   il_0006:  ldstr      ""   il_000b:  stloc.1   il_000c:  ldloc.0   il_000d:  callvirt   instance void [system]system.diagnostics.stopwatch::start()   il_0012:  ldc.i4.0   il_0013:  stloc.2   il_0014:  br.s       il_0070   il_0016:  ldarg.1   il_0017:  ldc.i4.1   il_0018:  bne.un.s   il_0029   il_001a:  ldstr      "60%"   il_001f:  stloc.3   il_0020:  ldstr      "60%"   il_0025:  stloc.s    width   il_0027:  br.s       il_0036   il_0029:  ldstr      "80%"   il_002e:  stloc.3   il_002f:  ldstr      "80%"   il_0034:  stloc.s    width   il_0036:  ldc.i4.5   il_0037:  newarr     [mscorlib]system.string   il_003c:  stloc.s    cs$0$0000   il_003e:  ldloc.s    cs$0$0000   il_0040:  ldc.i4.0   il_0041:  ldstr      "height: "   il_0046:  stelem.ref   il_0047:  ldloc.s    cs$0$0000   il_0049:  ldc.i4.1   il_004a:  ldloc.3   il_004b:  stelem.ref   il_004c:  ldloc.s    cs$0$0000   il_004e:  ldc.i4.2   il_004f:  call       string [mscorlib]system.environment::get_newline()   il_0054:  stelem.ref   il_0055:  ldloc.s    cs$0$0000   il_0057:  ldc.i4.3   il_0058:  ldstr      "width: "   il_005d:  stelem.ref   il_005e:  ldloc.s    cs$0$0000   il_0060:  ldc.i4.4   il_0061:  ldloc.s    width   il_0063:  stelem.ref   il_0064:  ldloc.s    cs$0$0000   il_0066:  call       string [mscorlib]system.string::concat(string[])   il_006b:  stloc.1   il_006c:  ldloc.2   il_006d:  ldc.i4.1   il_006e:  add   il_006f:  stloc.2   il_0070:  ldloc.2   il_0071:  ldc.i4     0xf4240   il_0076:  blt.s      il_0016   il_0078:  ldloc.0   il_0079:  callvirt   instance void [system]system.diagnostics.stopwatch::stop()   il_007e:  ldstr      "testifelse.txt"   il_0083:  ldloc.1   il_0084:  call       void [mscorlib]system.io.file::writealltext(string,                                                                    string)   il_0089:  ldloc.0   il_008a:  callvirt   instance int64 [system]system.diagnostics.stopwatch::get_elapsedmilliseconds()   il_008f:  ret } // end of method frmresearch::withifandelse 

block #2

.method public hidebysig instance int64  withonlyif(int32 myflag) cil managed {   // code size       142 (0x8e)   .maxstack  3   .locals init ([0] class [system]system.diagnostics.stopwatch mytimer,            [1] string somestring,            [2] int32 i,            [3] string height,            [4] string width,            [5] string[] cs$0$0000)   il_0000:  newobj     instance void [system]system.diagnostics.stopwatch::.ctor()   il_0005:  stloc.0   il_0006:  ldstr      ""   il_000b:  stloc.1   il_000c:  ldloc.0   il_000d:  callvirt   instance void [system]system.diagnostics.stopwatch::start()   il_0012:  ldc.i4.0   il_0013:  stloc.2   il_0014:  br.s       il_006e   il_0016:  ldstr      "80%"   il_001b:  stloc.3   il_001c:  ldstr      "80%"   il_0021:  stloc.s    width   il_0023:  ldarg.1   il_0024:  ldc.i4.1   il_0025:  bne.un.s   il_0034   il_0027:  ldstr      "60%"   il_002c:  stloc.3   il_002d:  ldstr      "60%"   il_0032:  stloc.s    width   il_0034:  ldc.i4.5   il_0035:  newarr     [mscorlib]system.string   il_003a:  stloc.s    cs$0$0000   il_003c:  ldloc.s    cs$0$0000   il_003e:  ldc.i4.0   il_003f:  ldstr      "height: "   il_0044:  stelem.ref   il_0045:  ldloc.s    cs$0$0000   il_0047:  ldc.i4.1   il_0048:  ldloc.3   il_0049:  stelem.ref   il_004a:  ldloc.s    cs$0$0000   il_004c:  ldc.i4.2   il_004d:  call       string [mscorlib]system.environment::get_newline()   il_0052:  stelem.ref   il_0053:  ldloc.s    cs$0$0000   il_0055:  ldc.i4.3   il_0056:  ldstr      "width: "   il_005b:  stelem.ref   il_005c:  ldloc.s    cs$0$0000   il_005e:  ldc.i4.4   il_005f:  ldloc.s    width   il_0061:  stelem.ref   il_0062:  ldloc.s    cs$0$0000   il_0064:  call       string [mscorlib]system.string::concat(string[])   il_0069:  stloc.1   il_006a:  ldloc.2   il_006b:  ldc.i4.1   il_006c:  add   il_006d:  stloc.2   il_006e:  ldloc.2   il_006f:  ldc.i4     0xf4240   il_0074:  blt.s      il_0016   il_0076:  ldloc.0   il_0077:  callvirt   instance void [system]system.diagnostics.stopwatch::stop()   il_007c:  ldstr      "testif.txt"   il_0081:  ldloc.1   il_0082:  call       void [mscorlib]system.io.file::writealltext(string,                                                                    string)   il_0087:  ldloc.0   il_0088:  callvirt   instance int64 [system]system.diagnostics.stopwatch::get_elapsedmilliseconds()   il_008d:  ret } // end of method frmresearch::withonlyif 

so can if-else block(block #1) runs faster if block(block #2) pointed many in forum.

test results

10,000,000 iterations of block 1

myflag = 0:    23.8ns per iteration myflag = 1:    23.8ns per iteration 

10,000,000 iterations of block 2

myflag = 0:    23.8ns per iteration myflag = 1:    46.8ns per iteration 

block 2 96% slower block 1. makes sense, since block 2 twice work in pessimistic case.

i prefer either case, depending on situation. if myflag rarely ever 1, want stand out edge case have handle. if both equally likely, want if-else syntax. that's preference, not fact.


decades ago, intel 80286 dual pipeline stall if conditional jump taken, rather falling through next instruction. time of pentium went away; cpu pre-fetches both branch paths. in of mind still have twinge of fear whenever write code has common outcome in else clause. every time have remind myself doesn't matter anymore.


int32 reps = 10000000;  private void block1(int myflag) {     string width;     string height;      stopwatch sw = new stopwatch();     sw.start();     (int = 0; < reps; i++)     {         if (myflag == 1)         {             width = string.format("{0:g}%", 60);             height = string.format("{0:g}%", 60);         }         else         {             width = string.format("{0:g}%", 80);             height = string.format("{0:g}%", 80);         }     }     sw.stop();     double time = (double)sw.elapsed.ticks / stopwatch.frequency * 1000000000.0 / reps;     messagebox.show(time.tostring() + " ns"); }  private void block2(int myflag) {     string width;     string height;      stopwatch sw = new stopwatch();     sw.start();     (int = 0; < reps; i++)     {         width = string.format("{0:g}%", 80);         height = string.format("{0:g}%", 80);         if (myflag == 1)         {             width = string.format("{0:g}%", 60);             height = string.format("{0:g}%", 60);         }     }     sw.stop();      double time = (double)sw.elapsed.ticks / stopwatch.frequency * 1000000000.0 / reps;     messagebox.show(time.tostring() + " ns"); } 
  • string.format makes if 96% slower
  • getpercentagestring(0.60) makes if 96% slower

const    reps = 10000000;  procedure block1(myflag: integer); var    width, height: string;    i: integer;    t1, t2: int64;    time: extended;    freq: int64; begin    queryperformancecounter(t1);    := 1 reps    begin       if myflag = 1       begin          width := '60%';          height := '60%';       end       else       begin          width := '80%';          height := '80%';       end;    end;    queryperformancecounter(t2);    queryperformancefrequency(freq);     time := (t2-t1) / freq * 1000000000 / reps;    showmessage(floattostr(time)+ 'ns'); end;  procedure block2(myflag: integer); var    width, height: string;    i: integer;    t1, t2: int64;    time: extended;    freq: int64; begin    queryperformancecounter(t1);    := 1 reps    begin       width := '80%';       height := '80%';       if myflag = 1       begin          width := '60%';          height := '60%';       end;    end;    queryperformancecounter(t2);    queryperformancefrequency(freq);     time := (t2-t1) / freq * 1000000000 / reps;    showmessage(floattostr(time)+ 'ns'); end; 

doing twice amount of work takes twice amount of time.

answer: if not perform better if-else.


enter image description here


Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -