Daily using/supporting

Get Firefox browser!
Get Thunderbird!
Get Opera browser!
Get The Gimp!
Get Inkscape!
Get LibreOffice!
Get Videolan!
Get Linux!
Get Mandriva!
Get Joomla!
Hacker Emblem

Archives

Which topics would you like us to cover more?

Latest comments

Latest tweets

about 1 day ago Using REDIPS.drag to add drag and drop to your .Net webapplication #li #dib0 http://t.co/n8zY3s7d
about 7 days ago http://t.co/cknQcDbo #Kindle
about 15 days ago Freedom isn't the ability to choose what to do or say, but the ability to choose what not to do or say #freedom
about 29 days ago http://t.co/61KTQknI #Kindle
12 Apr 2012 Force the use of a networking adapter using C# #li #dib0 http://t.co/ZTJOPzOz
9 Apr 2012 Mandriva 2010.2 and USB devices in Virtualbox http://t.co/fwq9gbHB
9 Apr 2012 Execute a http request to you own site with PHP http://t.co/DIvWPrpd
Home Architecture, security and coding Are break-statements (in Java and .Net) as bad as taught to me?
Are break-statements (in Java and .Net) as bad as taught to me?
Written by Division by Zero   
Thursday, 31 December 2009 15:17
Back in my days as a student I learned tha using the break statement is bad programming. Of course using the break statement within a switch statement is an exception to this rule. Since then I became a C# developer and I come across a lot of break statements in code of other developers. After a lot of (fun and usefull) discussion about this, it's time to put it to the test.

One of the reasons why it's a bad coding practice is that the break statement messes up the the branch prediction of the processor. While this is probably true for languages like C++, the question is if it is true for Java and C#, which are not directly compiled to assembly. I used these two methods to test if a break statement is actually slower than not using a break.
private const int totalAmountOfNumbers = 1000000;
private static int[] numbers;
private static Random random = new Random((int)DateTime.Now.Ticks);

private static bool DoSomethingWithBreak(int numberToFind)
{
 bool found = false;

 foreach (int number in numbers)
 {
 found = (number == numberToFind);
 
 if (found)
 break;
 }

 return found;
}

private static bool DoSomethingWithoutBreak(int numberToFind)
{
 bool found = false;

 for (int i = 0; (i < numbers.Length) && (!found); i++)
 {
 found = (numbers[i] == numberToFind);
 }

 return found;
}


Compiled to IL code these methods look like this.
.method private hidebysig static bool  DoSomethingWithBreak(int32 numberToFind) cil managed
{
 // Code size       36 (0x24)
 .maxstack  2
 .locals init ([0] bool found,
 [1] int32 number,
 [2] int32[] CS$6$0000,
 [3] int32 CS$7$0001)
 IL_0000:Â  ldc.i4.0
 IL_0001:Â  stloc.0
 IL_0002:  ldsfld     int32[] ConsoleApplication1.Program::numbers
 IL_0007:Â  stloc.2
 IL_0008:Â  ldc.i4.0
 IL_0009:Â  stloc.3
 IL_000a:  br.s       IL_001c
 IL_000c:Â  ldloc.2
 IL_000d:Â  ldloc.3
 IL_000e:Â  ldelem.i4
 IL_000f:Â  stloc.1
 IL_0010:Â  ldloc.1
 IL_0011:Â  ldarg.0
 IL_0012:Â  ceq
 IL_0014:Â  stloc.0
 IL_0015:Â  ldloc.0
 IL_0016:  brtrue.s   IL_0022
 IL_0018:Â  ldloc.3
 IL_0019:Â  ldc.i4.1
 IL_001a:Â  add
 IL_001b:Â  stloc.3
 IL_001c:Â  ldloc.3
 IL_001d:Â  ldloc.2
 IL_001e:Â  ldlen
 IL_001f:Â  conv.i4
 IL_0020:  blt.s      IL_000c
 IL_0022:Â  ldloc.0
 IL_0023:Â  ret
} // end of method Program::DoSomethingWithBreak

.method private hidebysig static bool  DoSomethingWithoutBreak(int32 numberToFind) cil managed
{
 // Code size       36 (0x24)
 .maxstack  2
 .locals init ([0] bool found,
 [1] int32 i)
 IL_0000:Â  ldc.i4.0
 IL_0001:Â  stloc.0
 IL_0002:Â  ldc.i4.0
 IL_0003:Â  stloc.1
 IL_0004:  br.s       IL_0015
 IL_0006:  ldsfld     int32[] ConsoleApplication1.Program::numbers
 IL_000b:Â  ldloc.1
 IL_000c:Â  ldelem.i4
 IL_000d:Â  ldarg.0
 IL_000e:Â  ceq
 IL_0010:Â  stloc.0
 IL_0011:Â  ldloc.1
 IL_0012:Â  ldc.i4.1
 IL_0013:Â  add
 IL_0014:Â  stloc.1
 IL_0015:Â  ldloc.1
 IL_0016:  ldsfld     int32[] ConsoleApplication1.Program::numbers
 IL_001b:Â  ldlen
 IL_001c:Â  conv.i4
 IL_001d:  bge.s      IL_0022
 IL_001f:Â  ldloc.0
 IL_0020:  brfalse.s  IL_0006
 IL_0022:Â  ldloc.0
 IL_0023:Â  ret
} // end of method Program::DoSomethingWithoutBreak


So the foreach and the break statements generate more IL code, but this says nothing about the performance of the code. After running the methods a few thousend times and calculating the average execution time, the method with break took an average of 0.04 milliseconds and the method without the break took 0.088 milliseconds.

So... the break is faster, so the branch prediction argument doesn't hold. Are there more arguments for not using the break statement? Actually, none that I can think of. It's a readable statement (if the rest of the code is readable!). I stand corrected!
Tags:
 

Add comment


Security code
Refresh

Its name is Public Opinion. It is held in reverence. It settles everything. Some think it is the voice of God. - Mark Twain


© 2009 - 2012, Division by Zero

Template based on the empire template by joomlashack 

Valid XHTML 1.0 Strict  Valid CSS!  Creative Commons License
This work by Division by Zero is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Netherlands License.