Post Reply 
Checking conditions [IF ... THEN ... ELSE] performance
09-14-2015, 06:24 PM (This post was last modified: 09-14-2015 08:17 PM by komame.)
Post: #1
Checking conditions [IF ... THEN ... ELSE] performance
Hi,

I wonder if the checking conditions in HPPL are working properly.
It looks that all of the AND conditions are always executed even if first one returns false.
The same problem is for the OR conditions when the the first return true.

For example, if the expression is composed of three conditions and each of them is false then there is no need to check each of them. This is how languages C, C#, Java and other works.

HPPL seems to check every time all the conditions which may greatly slow down the program execution.

I did a little test for three conditions that each of them return false:

Example:
Code:
EXPORT TESTCONDITIONS()
BEGIN
  LOCAL a,b,x,t;
  [[1,2,3],[4,5,6],[7,8,9]]▶a;
  PRINT();
//first test
  0▶b;
  TICKS▶t;
  FOR x FROM 1 TO 10000 DO
    IF a[3,2]=7 AND a[1,1]=4 AND a[3,3]=8 THEN
      b+1▶b;
    END;
  END;
  PRINT(TICKS-t);
//second test
  0▶b;
  TICKS▶t;
  FOR x FROM 1 TO 10000 DO
    IF a[3,2]=7 THEN
      IF a[1,1]=4 THEN
        IF a[3,3]=8 THEN
          b+1▶b;
        END;
      END;
    END;
  END;
  PRINT(TICKS-t);
END;

When the program finishes there will be two measurements of time.
First is about 750 [ms] and the second id 360 [ms].
The first is test of 10000 times of three conditions using AND, the second is the same but use of implantation conditions. In the second case the program ran twice as fast.

The conditions can be very complex, eg. a complex function which returns true or false. Then check each of them is a large loss of performance.

I think HPPL would work like in other languages which would greatly accelerate programs execution.
Find all posts by this user
Quote this message in a reply
09-14-2015, 07:21 PM
Post: #2
RE: Checking conditions [IF ... THEN ... ELSE] performance
I verified your observation for both the infix AND operator, and the prefix and() function. All 4 of the following lines return the correct answer, but they all take 5 seconds to execute. The WAIT command in the second pair of lines should not be executed, but it is.

IF 1==1 AND WAIT(5)==5 THEN "True" ELSE "False" END --> "True"
IF and(1==1,WAIT(5)==5) THEN "True" ELSE "False" END --> "True"

IF 1==2 AND WAIT(5)==5 THEN "True" ELSE "False" END --> "False"
IF and(1==2,WAIT(5)==5) THEN "True" ELSE "False" END --> "False"

<0|ɸ|0>
-Joe-
Visit this user's website Find all posts by this user
Quote this message in a reply
09-14-2015, 07:36 PM (This post was last modified: 09-14-2015 07:39 PM by Tim Wessman.)
Post: #3
RE: Checking conditions [IF ... THEN ... ELSE] performance
I believe it is working as designed. I'm not sure if there is a generic way we can handle this due to PPL being both a math language, and program language though.

I've put it on the list to look at conditional short circuiting. If anything, I suspect the AND priority is what is impacting things here. Since it needs to be lower then other operators/functions it is most likely not evaluating till everything else has completed. Might not be a simple, general solution for this though...

TW

Although I work for HP, the views and opinions I post here are my own.
Find all posts by this user
Quote this message in a reply
09-14-2015, 09:01 PM (This post was last modified: 09-14-2015 09:02 PM by komame.)
Post: #4
RE: Checking conditions [IF ... THEN ... ELSE] performance
Generaly each condition has two parts: before the operator and after the operator.

In the case of the OR operator the first part is always checked and if it returns True the second part should be skipped.
In the case of the AND operator the first part is always checked and if it returns False the second part should be skipped.

Code:
local a=1,b=2,c=3,d=4;

IF a==1 OR (b==2 AND c==4 OR d==4)  // the first part is [a==1] and the second part is the [(b==2 AND c==4 OR d==4)]
the first part returns True so all after the OR operator should be skipped.

IF a==2 AND (b==2 AND c==4 OR d==4)  // the first part is [a==2] and the second part is the [(b==2 AND c==4 OR d==4)]
the first part returns False so all after the AND operator should be skipped.

I believe that all programming languages are working that way.
Find all posts by this user
Quote this message in a reply
09-14-2015, 09:24 PM (This post was last modified: 09-14-2015 10:17 PM by primer.)
Post: #5
RE: Checking conditions [IF ... THEN ... ELSE] performance
(09-14-2015 09:01 PM)komame Wrote:  I believe that all programming languages are working that way.
yes, indeed, and it's also very usefull to perform consistance checking,
for example
Code:
if( var!=0 AND a/var > b)
here the AND does not check condition a/var> b if var is null. here you avoid checking with inconsistant value (zero denominator)

I mean it's not only a question of performance.
Regards.
Find all posts by this user
Quote this message in a reply
09-14-2015, 10:06 PM (This post was last modified: 09-14-2015 10:15 PM by roadrunner.)
Post: #6
RE: Checking conditions [IF ... THEN ... ELSE] performance
When time is an issue in any particular program the equivalent can be achieved with current PPL code using nested if's or the case function. Here's an example:

Code:
EXPORT eraseme1()
BEGIN
 if 1==1 then
  if wait(5)==5 then "true"; end;
 else "false"; end;
END;

export eraseme2()
begin
 if 1==2 then
  if wait(5)==5 then "true"; end;
 else "false"; end;
end;

eraseme1() returns "true" and takes 5 seconds to run while eraseme2() returns "false" and takes a fraction of a second to run.

-road
Find all posts by this user
Quote this message in a reply
09-15-2015, 05:04 AM
Post: #7
RE: Checking conditions [IF ... THEN ... ELSE] performance
(09-14-2015 09:01 PM)komame Wrote:  Generaly each condition has two parts: before the operator and after the operator.

In the case of the OR operator the first part is always checked and if it returns True the second part should be skipped.
In the case of the AND operator the first part is always checked and if it returns False the second part should be skipped. ...

I believe that all programming languages are working that way.

UBASIC both does and doesn't! It has two allowed syntaxes, infix and prefix, and they work differently:

Infix: A and B --> both expressions always get evaluated.

Prefix: and(A,B,C,...) --> evaluating from left to right, as soon as one of the arguments evaluates to 0, all subsequent arguments are skipped (unevaluated) and 0 is returned immediately.

Unfortunately HP-71 BASIC's "and" operator only has infix notation, and it always evaluates both expressions.

<0|ɸ|0>
-Joe-
Visit this user's website Find all posts by this user
Quote this message in a reply
09-15-2015, 05:25 AM
Post: #8
RE: Checking conditions [IF ... THEN ... ELSE] performance
Hello,

You are correct. All parameters are evaluated FIRST and then the AND operation is 'calculated'.

a statement of the form
a AND b AND c
will be represented as an evaluation tree of the form (in LISP)
(AND a, AND(b, c))

It will cause a to be evaluated, then b, then c, then the b AND c will be calculated, and finally the a AND result of AND(b,c)...
You can check that by replacing a, b and c by function call that print something on the screen and looking at the print order.

This difears from C type programming languages which do have OR/AND operator short circuiting.

This feels correct for math operation, but it is true that it is not optimal from a programming performance point of view.

Cyrille

Although I work for the HP calculator group, the views and opinions I post here are my own. I do not speak for HP.
Find all posts by this user
Quote this message in a reply
09-15-2015, 09:42 AM
Post: #9
RE: Checking conditions [IF ... THEN ... ELSE] performance
I tried a little code like the excel function andlist, to see if having the functions in a list rather than separately might help: it doesn't.

Then I tried implementing the execution of one of two functions passed as parameters:
If choice then fun1 else fun2 end if.
Again, it seems both fun1 and fun2 are executed simply by being parameters.

Am I understanding this correctly?

Code:

 
 RR(V)
 BEGIN
  IF V THEN
   PRINT("TRUE");
  ELSE
   PRINT("FALSE");
  END;
 END;
 
 FLS()
 BEGIN
  PRINT("FLS");
 RETURN 0;

 END;

 TRU()
 BEGIN
  PRINT("TRU");
  RETURN 1; 
 END;

 

 ZAND(A,B)
 BEGIN
  0▶R;
  IF A  THEN
   IF B THEN
     PRINT("WHY");
     1▶R;
   END;
  END;
  PRINT("R"+R);
 END;

 ZANDLST(LL)
 BEGIN
  LOCAL SOFAR:=1;
  LOCAL I:=1;
  PRINT("ZANDLST:");
  WHILE I≤SIZE(LL)  AND SOFAR DO
    SOFAR:=LL(I);
    PRINT(I+","+SOFAR);
  END;
  RR(SOFAR);
  RETURN SOFAR; 
 END;

 CHS(CHOICE,A,B)
 BEGIN
  IF CHOICE THEN
   PRINT("A CHOSEN");
   A();
  ELSE
   PRINT("B CHOSEN");
   B();
  END;
 END;

EXPORT ZANDTRY()
BEGIN
 PRINT();
 ZAND(FLS(),TRU());
 //PRINT("ZL");
 //ZANDLST({FLS(),TRU()});
 PRINT("CHOICE:");
 CHS(1,FLS(),TRU());
 
 WAIT;
END;

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: