Author Topic: The ternary operator's efficiency  (Read 331 times)

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
The ternary operator's efficiency
« on: January 01, 2012, 06:27:58 pm »


               Hi all,

I've read a few times that the ternary operator might be "more efficient" than an if statement, and I wonder how to interpret this regarding nwscript. Does the compiler produce better code with the first than with the latter or is it only shorter in the script itself?

Thanks for any info


Kato 
               
               

               


                     Modifié par Kato_Yang, 01 janvier 2012 - 06:31 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The ternary operator's efficiency
« Reply #1 on: January 01, 2012, 09:30:28 pm »


               My opinon is no.   Even though there may be cases where it would produce less instructions, The number of instructions excuted are normally about the same.  I feel that in most cases they just make the code harder to read.   Again my answer is given here without doing any experimentaion. 

I guess a simple example of how things are handled would help you understand the differance between the IF statment and the ternary operator. The main difference here being one is a statment where that other is an operator.  

int z = (x > y) ? x : y;

vs.

int z;
if (x>y) z=x; else z=y; 

 In nwscript we are dealing with a virtual machine so I will break this down in that context. The only real differance, as far as this example goes, is that everything that is returned, is returned to the VM stack.   Where in code compiled to machine instruction returns would normaly just be left(returned) in one of the regesters in the CPU to be used by the code that followed. 

Both forms above have the the Var 'z' declaired.   It really does not matter where the Var is declaired at in the script.  The compiler will create the code that reserves the memory loclation for the Var at the begining of the code, So there is no savings there. 

The ternary:  // we will ingnore he int declairation of z since it does not matter and is done either way. 
 
z = (x > y) ? x : y;

The first thing done here is the compairsion (x>y), . It is done something like the following. 
  • push x onto the top of the stack.
  • push y onto the top of the stack. 
  • Call the VM code that compairs the two INTs.  This code will remove x and y from the stack and leave the result (either 1 or 0 ) on the top of the VM stack.    
The next thing that is going to happen is branch in the code based on the result on the top of the stack.  Even though a compairsion has just been made another compairsion (test) will be made with value on the stack against 0 (False)   to decide if the code branches or not.  At this point I need a few lables defined.   The lables are nothing more then a Compile time Var used for where code is placed in memory.   I need two Lables one for where the False clause starts( the : in the statment), I will Call it  FalseClaus, and one for where the statment ends( the ; at the end of the statment )  I will call it EndofStatment.     
 
  • Branch if  0 to FalseClaus ;    This will remove the top of the stack and if it is 0 move the NextInstruction pointer to the value of the FalseClause Lable.   
 Right after the branch instruction is the TrueClaus there is no need for a lable here It is just not jumped over.   Our true Claus is simple it just moves x to the top of the stack then stores the value of EndofStatment  into the 'Next Instruction' Pointer  to . 
  •  push x onto the top of the stack.
  •  jump EndofStatment.    
Now we have the false clause, The label shown (:label) does not take up any memory in code. It is only a var used by the compiler during compile time to designate where to make branches to.    So the Value of FalseClaus would equal the position of the Push y instruction in the .ncs file.  ( or is that .nsc, ahh i don't remember).


  •   :FalseClaus
  •   push y onto the top of stack.
  •   :EndofStatment

Now  the assingment  will happen  with our resulf from the operator being on the top of the stack. with the only thing left after that being the removal of the result from the stack. 


mov TP  z  // Move the top of stack to  z,
DecStack INT,    Decrease the Top Of Stack pointer be the Size of an INT, Basicly removing it.  


Here it is without so many comments. 

z = (x > y) ? x : y;

  • push x onto the top of the stack.
  • push y onto the top of the stack. 
  • Call the VM code that compairs the two INTs.  This code will remove x and y from the stack and leave the result (either 1 or 0 ) on the top of the VM stack.    
  • Branch if  0 to FalseClaus ;    This will remove the top of the stack and if it is 0 move the NextInstruction pointer to the value of the FalseClause Lable.   

  •  push x onto the top of the stack.
  •  jump EndofStatment.    

  •   :FalseClaus
  •   push y onto the top of stack.

  •   :EndofStatment
  • mov TP  z  // Move the top of stack to  z,
  • DecStack INT,    Decrease the Top Of Stack pointer be the Size of an INT, Basicly removing it.  

  
Ok now for the If statment Hope you can follow it without all the comments, If not let me know.  

if (x>y) z=x; else z=y; 

  • push x onto the top of the stack.
  • push y onto the top of the stack. 
  • Call the VM code that compairs the two INTs.  This code will remove x and y from the stack and leave the result (either 1 or 0 ) on the top of the VM stack.    
  • Branch if  0 to FalseClaus ;    This will remove the top of the stack and if it is 0 move the NextInstruction pointer to the value of the FalseClause Lable. 



  •  push x onto the top of the stack.
  • mov TP  z  // Move the top of stack to  z,
  • DecStack INT
  •  jump EndofStatment.    

  •   :FalseClaus
  •   push y onto the top of stack.
  • mov TP  z  // Move the top of stack to  z,
  • DecStack INT
  •   :EndofStatment
 


So if you look at it you will notice that yes, there are fewer instructions in the ternary,  Are there fewer or nore excuted, No.

Hope all that made since,
L8.
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
The ternary operator's efficiency
« Reply #2 on: January 01, 2012, 10:02:13 pm »


               Hey, I love this, tyvm Lightfoot8! Way more instructive than what I was initially expecting from this topic. '<img'>


Kato