Author Topic: Execution speeds  (Read 464 times)

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« on: August 19, 2011, 08:09:01 am »


               Ok, inspired by Hardcore UFO's post , i have another speed of execution question.

Which executes the fastest and is less hungry, nested ifs or case statements?

and will using boolean operators in my if conditional slow down the process. should i just nest ifs?
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Execution speeds
« Reply #1 on: August 19, 2011, 08:19:49 am »


               These are so small gains that it shouldnt bother you its rather more about personal preference.

But switches allows more than ifs can.
1) you can input the function into switch statement so you dont need to declare it first as variable which is needed with nested ifs
2) (missing) break; command allows interesting techniques

anyway its said that switches are in the compiler actually "rewritten" back to nested ifs.
               
               

               
            

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« Reply #2 on: August 19, 2011, 08:30:08 am »


               thanks man, the gains may seem small, but when you are executing a lot of heavy script, and you are trying to account for the power (or lack thereof) of end users machines, this is very important.

so in conclusion then, if the switches are definitely compiled as nested ifs anyway, then switches are obviously the preferential option, for readability more than anything else.

but what about when i use a boolean operator in the conditional?

is



if (monkey==dead)
{
  if (wallet==full)
  {
      object oNewApe=GetNewMonkey();
  }


}

faster than


if ((monkey==dead) && (wallet==full))
{
   object oNewApe=GetNewMonkey();
}



would it be quicker if i needed a dog rather than a monkey too?
               
               

               


                     Modifié par Roddish, 19 août 2011 - 07:31 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Execution speeds
« Reply #3 on: August 19, 2011, 08:42:04 am »


               

Roddish wrote...

Ok, inspired by Hardcore UFO's post , i have another speed of execution question.

Which executes the fastest and is less hungry, nested ifs or case statements?

In a regular language the Case statment would be faster but would also take up more memory for the lookup table.
In nwn they are the same thing.
I also assumed that you meant chained if /else if statments.  nested if statments do not compair to a case statment.

and will using boolean operators in my if conditional slow down the process. should i just nest ifs?


you mean
if ( x && y)  // statment to do. 
opposed to

if (x) 
{
   if (y) / do something. 
}

well the two above will compile to the same thing so there is no differance. 

On the other end however

if ( x || y)  // do something
would compile to the same thing as.

if (x) // do something
else if (y) // Do the same thing.

the second choice just doubles the code for what to do. so the first option is better.   

Here is the thing about boolean operators.  they are only evaluated as far as they need to be to get the correct result.   so say you have a bunch of chained And (&&) operaters.  

if ( a && b && c && d && e && f) 
{code block}

In order for the code block to run a,b,c,d,e and f all have to be TRUE.   If even one is false the entire expression evaluates to FALSE.

that is as soon as the first false is found it does not eve check the rest of the conditions.
 
same thing with the OR operator(||)

if (a || b || c || d || e || f)
{ code block }

in this case only one of them need to be true.  so if a is TRUE the runtime code will never even check to see if b,c,d,e or f are TRUE.  it just does not matter for the results of the expression.

In short you gain nothing by not using the boolean operators and can in fact make the code slower or mor bloated by not using them.
               
               

               
            

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« Reply #4 on: August 19, 2011, 08:57:30 am »


               Thanks lightfoot mate. legend.

i'm used to programming in compilers where nested ifs are evaluated the fastest you see, so it's nice to not stumble into a new script/language when you have operational preconceptions that are just going to make life awkward.

don't suppose you want another earwax award? ive made two more since last we spoke.............
               
               

               
            

Legacy_Morbane

  • Jr. Member
  • **
  • Posts: 79
  • Karma: +0/-0
Execution speeds
« Reply #5 on: August 19, 2011, 08:58:54 am »


               This popular phenomenon is referred to as a "shortcircuit" in coders lingo.
               
               

               
            

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« Reply #6 on: August 19, 2011, 09:03:03 am »


               Did i mention how much i love these forums?

^^

You guys are the bees knees
               
               

               


                     Modifié par Roddish, 19 août 2011 - 08:03 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Execution speeds
« Reply #7 on: August 19, 2011, 09:06:32 am »


               Shadow did bring up a good point about the switch/case control structure.   With chained if /else if statments the closing  } is  always a jump(break) to the end of the if/else if  chain.  This is not the case with the switch/case control structure.  if the break code excution will simply fall through to the next case code block.

The largest draw back to the switch/case is that all of your cases have to be integers.
               
               

               
            

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« Reply #8 on: August 19, 2011, 09:09:40 am »


               yeah, that sucks, first thing i noticed, when i tried to case strings. i swore like a mother.

why is that?? if you could case select objects, that would be AWESOME.

OI BIOWARE!!! SORT IT OUT!!!


please
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Execution speeds
« Reply #9 on: August 19, 2011, 10:11:36 am »


               In order to understand why thy have to be intengers in the case statments. you need to understand the differance btween the switch and if statments.   chained if statments are compairsons followed by conditional jumps.  

So if you have

if ( x== 1 ||  y == 2 )
 it compairs x to one,  If x == one jumps to the code block for true. 
 if  x != 1 it fall through to the next compairson of Y == 2
assuming we fell through we check if y==2
if y != TRUE we jump to the end of the code block for TRUE.
if it is TRUE it just falls through to the TRUE code block.

in the assembled code you end up with something like. 

:x  int;    // a memory location set asside for the x varaiable
:y  int;    // x and y are both lables.
...
  mov eax, &x                 // move x into the eax regester.
  cmp eax,1                // UpDate the flags regesters as if we subtracted 1 form the eax regester. 
  jmpz &TrueBlock      //  jump to lable TrueBlock if the zero flag is set in the e-flags regester.(they where equal)   
  mov eax, &y               // move y into the eax regester.
  cmp eax, 2             // UpDate the flags regesters as if we subtracted 2 form the eax regester. 
  jmpnz &EndIf           // jump to the lable EndIf if the zero flag is not set ( y!=2)
:TrueBlock              // lable for where the true block begins.
  // code to excute for the
  // TRUE block goes here.
  ....
:EndIf                       // lable to mark the end of the If block. 


so basickly if x ==1 it never checks to see what y is equal to.  However if it is not Y will then be checked. 


This is not how switch/case work however, switch/cases are not comparsions. they are calculations into a look up table.   The look up table is nothing more then an array of memory locations to jump to.   I do not have time at the moment to write it out in assemble but here is the jist of it.  

switch(x)  
{
 case 1:
    // code for case 1. 
   break;
 case 2:
   //code for case 2.
   break; 
}

now a compairson between x and 1 is neven done.   instead it takes x and uses it as an index into a lookup table. the lookup table is an array of memory locations for where each code block starts.  The size of a memory address in 32 bit programming is 4 bytes.   So it takes the value of x multiplies it by four, then added the address, of the  begining of the lookup table.  it then jumps excution of the code to that location in memory.   so there are no compairsions made, Just one calculation and then an indrect jump to the code block.  

The breaks in the code would all be jumps to the lable at the end of the switch control structure.  if the breaks are absent the code in following code blocks will also be excuted untill a break is hit.
               
               

               


                     Modifié par Lightfoot8, 19 août 2011 - 09:15 .
                     
                  


            

Legacy_Roddish

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Execution speeds
« Reply #10 on: August 19, 2011, 12:04:51 pm »


               

Lightfoot8 wrote...

I do not have time at the moment to write it out in assemble



LOL!!! but then who does? '<img'>

Thanks again lightfoot man, your knowledge of the nwn engine inclines me to propose to you.

how you doin baby? come give daddy some sugar. *SMOOOOCH*
               
               

               
            

Legacy_virusman

  • Sr. Member
  • ****
  • Posts: 448
  • Karma: +0/-0
Execution speeds
« Reply #11 on: August 20, 2011, 12:01:48 pm »


               'case' in NWScript is actually translated to 'if' bytecodes, so there will be no difference.