ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

DOW x <= y is 3 times faster than using for x = number downto 1

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DOW x <= y is 3 times faster than using for x = number downto 1

    So I was looking at some code today that had a dow statement. Inside the loop, as you all know, you have to increment the counting variable yourself. So I thought... what if I did this with a for statement and thought about the downto option... so in my testing to see if I need to go downto 1 or 0 I thought that I would do a quick performance test to see if the simpler looking "for" code ran quicker than the more manual "dow" code.

    BIG SURPRISE!!!!!

    In a test of 100,000,000 iterations the dow loop is 3 times faster than the for loop....

    Here's the code... feel free to test it out...
    Code:
         dx...
         d                 s             10i 0
         dy...
         d                 s             10i 0
         dcounter...
         d                 s             10i 0
         d
         d*****************TIMER VARIABLES****************
         d starttime...
         d                 s               z
         d time_taken...
         d                 s             15s 0
         d timediff...
         d                 s             40a
         d************************************************
          /free
            *inlr = *on;                                          
           x = 0;
           y = 0;
           counter = 0;
    
           starttime = %timestamp();
           for x = 100000000 downto 1;
           endfor;
           time_taken = %diff(%timestamp():starttime:*MSECONDS);
           timediff = %char(time_taken);
           dsply timediff;
    
    
           counter = 0;
           x = 1;
           y = 100000000;
    
           starttime = %timestamp();
           dow x <= y;
             x+=1;
           enddo;
           time_taken = %diff(%timestamp():starttime:*MSECONDS);
           timediff = %char(time_taken);
           dsply timediff;                                               
          /end-free
    Now, I realize that this is at the mseconds level, but think of all the loops we have in our code...
    Your future President
    Bryce

    ---------------------------------------------
    http://www.bravobryce.com

  • #2
    Re: DOW x <= y is 3 times faster than using for x = number downto 1

    Nice test .... just for fun time this

    PHP Code:
    for 1 to 100000000
    All my answers were extracted from the "Big Dummy's Guide to the As400"
    and I take no responsibility for any of them.

    www.code400.com

    Comment


    • #3
      Re: DOW x <= y is 3 times faster than using for x = number downto 1

      for x = 100000000 downto 1; <--------3280000

      for x = 1 to 100000000; <--------3705000

      dow x <= y; y=100000000 <--------1100000


      I can't believe that it was worse yet....

      Ran the test multiple times.... numbers above are just from one run, but the ratios are consistent.
      Your future President
      Bryce

      ---------------------------------------------
      http://www.bravobryce.com

      Comment


      • #4
        Re: DOW x <= y is 3 times faster than using for x = number downto 1

        i think this would speed it up interesting.

        PHP Code:
        for 1 to 100000000 by 100000000
        All my answers were extracted from the "Big Dummy's Guide to the As400"
        and I take no responsibility for any of them.

        www.code400.com

        Comment


        • #5
          Re: DOW x <= y is 3 times faster than using for x = number downto 1

          yeah...speeds up just a little
          Your future President
          Bryce

          ---------------------------------------------
          http://www.bravobryce.com

          Comment


          • #6
            Re: DOW x <= y is 3 times faster than using for x = number downto 1

            Hmm interesting analysis. Is there a point upto which the FOR might be faster than the DOW? Say 100 or 1000 iterations instead of 100,000,000? or does the ratio stay the same even at these number of iterations?

            Comment


            • #7
              Re: DOW x <= y is 3 times faster than using for x = number downto 1

              That is really interesting and just made some test here on my machine. To make a long story short: with nearly the same results. There is also no "break even point" where for gets faster than DoX related to the number of iterations.

              What I additionally experienced was the fact that you can speed up the for loops slightly by adding the "by 1" phrase.

              On my system, a power 7 with 6 cores and nothing to do but waiting for those weired experimets of Code400 and me it took nearly the same amout of time as the other posters reported.

              To eleminate the possibility of side effect I changed the code of the for loops so it uses variables instead of constants. I compared decrements and increments. Barely noticable but reproducable there is a slight performance benefit for incrementing loops.

              Here is my version of the test program:

              Code:
                   dx...
                   d                 s             10i 0
                   dy...
                   d                 s             10i 0
                   dstep...
                   d                 s             10i 0
                   dLowerLimit...
                   d                 s             10i 0 inz(1)
                   dUpperLimit...
                   d                 s             10i 0 inz(100000000)
                   d
                   d*****************TIMER VARIABLES****************
                   d starttime...
                   d                 s               z
                   d time_taken...
                   d                 s             15s 0
                   d timediff...
                   d                 s             50a
                   d************************************************
                    /free
                      *inlr = *on;
              
                     // For loop decrement
                     x = UpperLimit;
                     y = LowerLimit;
                     step = 1;
              
                     starttime = %timestamp();
                     for x by step downto y;
                     endfor;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'For loop decr: ' + %char(time_taken);
                     dsply timediff;
              
              
                     // For loop increment
                     x = LowerLimit;
                     y = UpperLimit;
                     step = 1;
              
                     starttime = %timestamp();
                     for x by step to y;
                     endfor;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'For loop incr: ' + %char(time_taken);
                     dsply timediff;
              
              
                     // Dow loop decrement
                     step = 1;
                     x = UpperLimit;
                     y = LowerLimit;
              
                     starttime = %timestamp();
                     dow x >= y;
                       x -= step;
                     enddo;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'DoW loop decr: ' + %char(time_taken);
                     dsply timediff;
              
              
                     // Dow loop increment
                     step = 1;
                     x = LowerLimit;
                     y = UpperLimit;
              
                     starttime = %timestamp();
                     dow x <= y;
                       x += step;
                     enddo;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'DoW loop incr: ' + %char(time_taken);
                     dsply timediff;
              
              
                     // Dou loop decrement
                     step = 1;
                     x = UpperLimit;
                     y = LowerLimit;
              
                     starttime = %timestamp();
                     dou x < y;
                       x -= step;
                     enddo;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'DoU loop decr: ' + %char(time_taken);
                     dsply timediff;
              
              
                     // Dou loop increment
                     step = 1;
                     x = LowerLimit;
                     y = UpperLimit;
              
                     starttime = %timestamp();
                     dou x > y;
                       x += step;
                     enddo;
                     time_taken = %diff(%timestamp():starttime:*MSECONDS);
                     timediff = 'DoU loop incr: ' + %char(time_taken);
                     dsply timediff;
                    /end-free
              Anyone out there who wants to compare GOTO - TAG loops against the rest
              Sven

              The best way to prove your knowledge is to share it ...

              Comment


              • #8
                Re: DOW x <= y is 3 times faster than using for x = number downto 1

                ... I could not resist and tried myself

                Code:
                     c                   eval      starttime = %timestamp()
                     c                   Z-Add     1             step
                     c                   Z-Add     LowerLimit    x
                     c                   Z-Add     UpperLimit    y
                     c     top           TAG
                     c                   add       step          x
                     c     x             cable     y             top
                     c                   eval      time_taken = %diff(%timestamp()
                     c                                                :starttime:*MSECONDS)
                     c                   eval      timediff='CABxx Loop incr:'+%char(time_taken)
                     c                   dsply                   timediff
                DSPLY For loop decr: 2173000
                DSPLY For loop incr: 2167000
                DSPLY DoW loop decr: 698000
                DSPLY DoW loop incr: 709000
                DSPLY DoU loop decr: 715000
                DSPLY DoU loop incr: 711000
                DSPLY CABxx Loop incr:678000

                Seems the good old GOTO-TAG construct has the same permormance as the Do loops ...

                After thinking a bit about the situation and the possible causes I had the idea that it could be caused by the representation of internal variables for the for loop. First I changed the type of the border values from 10i 0 to 11p 0 with the following results:

                DSPLY For loop decr: 7581000
                DSPLY For loop incr: 7659000
                DSPLY DoW loop decr: 6500000
                DSPLY DoW loop incr: 6697000
                DSPLY DoU loop decr: 6538000
                DSPLY DoU loop incr: 6582000
                DSPLY CABxx Loop incr:7202000

                ... about 3 to 10 times longer!! and now the different types of loop constructs got similar run times ...

                But it gets even worse. Just changed the types to zoned 11s 0 ...

                DSPLY For loop decr: 10885000
                DSPLY For loop incr: 11284000
                DSPLY DoW loop decr: 10299000
                DSPLY DoW loop incr: 10201000
                DSPLY DoU loop decr: 10143000
                DSPLY DoU loop incr: 10271000
                DSPLY CABxx Loop incr:11712000

                So one simple rule for defining variables for loop processing use always integer types!! and the loops are 3 to 10 times faster ...

                I will just continue investigating ...
                Sven

                The best way to prove your knowledge is to share it ...

                Comment


                • #9
                  Re: DOW x <= y is 3 times faster than using for x = number downto 1

                  I always felt incrementing loops were better from a performance point of view considering add operations are usually done faster as compared to substractions.

                  Also GOTO - TAG looping seems a tad bit faster than DOW loops (and hence faster than FOR loops as well)

                  PHP Code:
                  DStartTime        S               z
                  DEndTime          S               z
                  DTimeDiff         S             20A
                  Dx                S             10i 0 inz
                  (1)
                  Dy                S             10i 0 inz(100000000)
                   /
                  Free
                      StartTime 
                  = %Timestamp();
                      
                  Dow x<y;
                         
                  x=x+1;
                      
                  enddo;
                      
                  EndTime = %Timestamp();
                      
                  TimeDiff = %Char(%Diff(EndTime:StartTime:*MSECONDS));
                      
                  Dsply TimeDiff;

                      
                  StartTime = %Timestamp();
                      
                  Reset x;
                      
                  Reset y;
                   /
                  End-Free
                  C     TEST          TAG
                  C     X             IFLT      Y
                  C     X             ADD       1             X
                  C                   
                  GOTO      TEST
                  C                   
                  ENDIF
                   /
                  Free
                      EndTime 
                  = %Timestamp();
                      
                  TimeDiff = %Char(%Diff(EndTime:StartTime:*MSECONDS));
                      
                  Dsply TimeDiff;
                      *
                  Inlr = *On;
                   /
                  End-Free 
                  Dont even ask about the closing and reopening of /free. Its been a long time since I actually used gotos and that too with the old column specific coding style.

                  Edit (After Sven's post): @#%@#%@#%@#% so using only integer variables, the GOTO loops are a tad bit faster but when using packed and zone decimals its slower....

                  Hmm very interesting indeed. Not to mention the speed of the other loops themselves.
                  Last edited by vikramx; June 17, 2011, 02:00 AM.

                  Comment


                  • #10
                    Re: DOW x <= y is 3 times faster than using for x = number downto 1

                    Next performance boost for the DoX loops:
                    If you compile the program with the option OPTIMIZE(*FULL) then the DoX loops gets more than 12 times faster than the For loops ...

                    DSPLY For loop decr: 2051000
                    DSPLY For loop incr: 2051000
                    DSPLY DoW loop decr: 165000
                    DSPLY DoW loop incr: 165000
                    DSPLY DoU loop decr: 166000
                    DSPLY DoU loop incr: 165000
                    DSPLY CABxx Loop incr:161000

                    ...
                    To be continued ...
                    Sven

                    The best way to prove your knowledge is to share it ...

                    Comment


                    • #11
                      Re: DOW x <= y is 3 times faster than using for x = number downto 1

                      Another well known loop construct in legacy coding:

                      Code:
                           c                   eval      starttime = %timestamp()
                           c                   Z-Add     1             step
                           c                   Z-Add     LowerLimit    x
                           c                   Z-Add     UpperLimit    y
                           c     top2          TAG
                           c                   add       step          x
                      [COLOR="red"]     c     x             comp      y                                    5050
                           c   50              goto      top2
                      [/COLOR]     c                   eval      time_taken = %diff(%timestamp()
                           c                                                :starttime:*MSECONDS)
                           c                   eval      timediff='COMP Loop incr:'+%char(time_taken)
                           c                   dsply                   timediff
                      This construct performs worse than the cabxx cunstruct:

                      DSPLY CABxx Loop incr:740000
                      DSPLY COMP loop incr:1466000

                      ... seems that construct results in two if statements ...
                      Sven

                      The best way to prove your knowledge is to share it ...

                      Comment


                      • #12
                        Re: DOW x <= y is 3 times faster than using for x = number downto 1

                        Hi

                        All this tests are done in interactive enviroment. Times may vary because of how system is busy. Continue testing in batch enviroment an then take care of CPU time used to complete different jobs. This result will be more efficient and comparable between different models and procesors of systems in use.
                        LP Zdenko

                        Comment


                        • #13
                          Re: DOW x <= y is 3 times faster than using for x = number downto 1

                          Well considering its the ratios that we are looking at here, I dont see it varying much from system to system. The individual times may be different based on processor power and system utilization but the ratio of the elapsed times would still be fairly consistent (unless the environment for running both tests changes drastically).

                          Comment


                          • #14
                            Re: DOW x <= y is 3 times faster than using for x = number downto 1

                            Hi Zdenko,
                            as stated before, I am pretty alone on my system, and I did at least 10 runs of the tests without remarkable differences from run to run.

                            Btw, due to the fact, that most batchjobs ar running with a priority of 50 these runs will get more affected by concurrent interactive jobs than an interactive job. So in batch environment the test results will be (depending on the workload of the system) less exact than in interctive environment. And the ratio of the cpu time consumed is comparable to the running times. So in most cases my test ran without any long wait ...
                            Sven

                            The best way to prove your knowledge is to share it ...

                            Comment


                            • #15
                              Re: DOW x <= y is 3 times faster than using for x = number downto 1

                              the variable type differences aren't really surprising. any numeric (packed or zoned) with zero decimals are "converted" to integers prior to math instructions. for packed decimals with > zero decimals are processed as packed. any zoned numeric with > zero decimals is converted to packed prior to math instructions.
                              I'm not anti-social, I just don't like people -Tommy Holden

                              Comment

                              Working...
                              X