Announcement

Collapse
No announcement yet.

Which is faster / more efficient?

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

  • Which is faster / more efficient?

    Here's a fundamental question to the way PB executables behave:

    Which of the following is faster / more efficient?

    1) Three separate single-dimension arrays all dimensioned to the same value:

    A(#)
    B(#)
    C(#)

    ...or

    2) A single three-dimensional array:

    ABC(3, #)


    ...where
    ABC(1, #) = A(#)
    ABC(2, #) = B(#)
    ABC(3, #) = C(#)

    So that these two statements would be equivalent:

    If A(123) = 10 and B(123) = 5.41 and C(123) = 1000 then

    If ABC(1, 123) = 10 and ABC(2, 123) = 5.41 and C(3, 123) = 1000 then

    The data are all related and will always be dimensioned to the same index.

    I don't care about the look of the resulting coding, I'm curious which will execute faster when compiled.

    ???

    Many thanks,
    --Tom
    Tom Brodhead

  • #2
    Tom --

    Without trying it... I'd speculate that the one-dimensional arrays would be faster, but by such a small amount that it would be hard to measure unless you are going absolutely crazy with array access.

    The reason I say that is that to access a multi-dim array, PB has to perform some relatively trivial math at runtime, which it doesn't have to do for the single-dim arrays.

    I'm pretty sensitive to speed issues -- old habits dies hard -- but this is an area where I would opt for the most readable and maintainable code. I would expect the speed difference to be insignificant.

    -- Eric
    "Not my circus, not my monkeys."

    Comment


    • #3
      Originally posted by Eric Pearson View Post
      ...I would opt for the most readable and maintainable code.
      Me too, and that would be the three arrays by about a mile. Regarding speed, it would be so easy to write a few lines of code to test it.

      Comment


      • #4
        The separate arrays were about twice as fast on my laptop using the code below. And separate arrays were even faster when I had a() and c() DIMMED as LONG.

        Code:
        #COMPILE EXE
        #DIM ALL
        #INCLUDE "win32api.inc"
        
        FUNCTION PBMAIN () AS LONG
            DIM a(1000) AS SINGLE, b(1000) AS SINGLE, c(1000) AS SINGLE
            DIM abc2(2, 1000) AS SINGLE
            LOCAL q1, q2 AS QUAD, ii AS LONG
            queryPerformanceCounter(q1)
            FOR ii = 1 TO 1000000
               IF A(123) = 10 AND B(123) = 5.41 AND C(123) = 1000 THEN    '<< this method was approx 2x faster on my machine
                 !nop
               END IF
            NEXT
            queryPerformanceCounter(q2)
            ? STR$(q2 - q1)
            queryPerformanceCounter(q1)
            FOR ii = 1 TO 1000000
               IF abc2(0, 123) = 10 AND abc2(1, 123) = 5.41 AND abc2(2, 123) = 1000 THEN
                 !nop
               END IF
            NEXT
            queryPerformanceCounter(q2)
            ? STR$(q2 - q1)
        
        END FUNCTION

        Comment


        • #5
          > And separate arrays were even faster when I had a() and c() DIMMED as LONG.

          Of course it was faster. Using PB/Windows or CC - when you have a choice - LONG is the 'variable type of choice' for performance considerations. It's in the help file.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            On my machine UDTs are faster than three separate arrays.

            John Gleason, I added to your code. Hope you don't mind.



            Code:
            #COMPILE EXE
            #DIM ALL
            #INCLUDE "win32api.inc"
            
            TYPE udtType
                a AS SINGLE
                b AS SINGLE
                c AS SINGLE
            END TYPE
            
            FUNCTION PBMAIN () AS LONG
                DIM a(1000) AS SINGLE, b(1000) AS SINGLE, c(1000) AS SINGLE
                DIM abc2(2, 1000) AS SINGLE
                DIM udt(1000) AS UDTType
                
                LOCAL q1, q2 AS QUAD, ii AS LONG
                queryPerformanceCounter(q1)
                FOR ii = 1 TO 1000000
                   IF A(123) = 10 AND B(123) = 5.41 AND C(123) = 1000 THEN    '<< this method was approx 2x faster on my machine
                     !nop
                   END IF
                NEXT
                queryPerformanceCounter(q2)
                ? STR$(q2 - q1)
                queryPerformanceCounter(q1)
                FOR ii = 1 TO 1000000
                   IF abc2(0, 123) = 10 AND abc2(1, 123) = 5.41 AND abc2(2, 123) = 1000 THEN
                     !nop
                   END IF
                NEXT
                queryPerformanceCounter(q2)
                ? STR$(q2 - q1)
                
                queryPerformanceCounter(q1)
                FOR ii = 1 TO 1000000
                   IF udt(123).a = 10 AND udt(123).b = 5.41 AND udt(123).c = 1000 THEN
                     !nop
                   END IF
                NEXT
                queryPerformanceCounter(q2)
                ? STR$(q2 - q1)
                
            
            END FUNCTION

            Comment


            • #7
              On my machine UDTs are faster than three separate arrays.
              That's interesting Brian. I tested it and it seemed about the same or even slower than the separate arrays, but still quite a bit faster than the two dimensional array. Probably it's processor related.

              John Gleason, I added to your code. Hope you don't mind.
              I do mind because that code was secret. Don't even look at that code. j/k
              Actually tho, I did a couple more tests--see code below--where all the operators were working in the statements, and the speed advantage reduced to only about 1.6x faster for the separate arrays. I'd be interested to know how it runs on your machine, and if you try the UDT with that code, is it still faster than separate arrays?

              > And separate arrays were even faster when I had a() and c() DIMMED as LONG.

              Of course it was faster. Using PB/Windows or CC - when you have a choice - LONG is the 'variable type of choice' for performance considerations. It's in the help file.
              What I meant to show there is that three separate arrays allow different type dimensioning for each array, hence another opportunity for optimization. The two dimensional array is locked into one type.

              Code:
              #COMPILE EXE
              #DIM ALL
              #INCLUDE "win32api.inc"
              
              FUNCTION PBMAIN () AS LONG
                  DIM a(1000) AS SINGLE, b(1000) AS SINGLE, c(1000) AS SINGLE
                  DIM abc2(2, 1000) AS SINGLE
                  LOCAL q1, q2 AS QUAD, ii, ii2 AS LONG
                  FOR ii = 0 TO 1000
                     abc2(0, ii) = ii
                     abc2(1, ii) = ii
                     abc2(2, ii) = ii
                     a(ii) = ii
                     b(ii) = ii
                     c(ii) = ii
                  NEXT
                  queryPerformanceCounter(q1)
                  FOR ii2 = 1 TO 1000
                  FOR ii = 0 TO 1000
                     IF A(ii) = ii AND B(ii) = ii AND C(ii) = ii THEN    '<< this method was approx 1.6x faster on my machine
                       !nop
                     END IF
                  NEXT
                  NEXT
                  queryPerformanceCounter(q2)
                  ? STR$(q2 - q1)
                  queryPerformanceCounter(q1)
                  FOR ii2 = 1 TO 1000
                  FOR ii = 0 TO 1000
                     IF abc2(0, ii) = ii AND abc2(1, ii) = ii AND abc2(2, ii) = ii THEN
                       !nop
                     END IF
                  NEXT
                  NEXT
                  queryPerformanceCounter(q2)
                  ? STR$(q2 - q1)
              
              END FUNCTION

              Comment


              • #8
                Originally posted by John Gleason View Post
                That's interesting Brian. I tested it and it seemed about the same or even slower than the separate arrays, but still quite a bit faster than the two dimensional array. Probably it's processor related.
                Yes. It is really close. Old code test udts are faster by about 10%.
                In new tests, the separate arrays are faster by about 10%.

                Actually tho, I did a couple more tests--see code below--where all the operators were working in the statements, and the speed advantage reduced to only about 1.6x faster for the separate arrays. I'd be interested to know how it runs on your machine, and if you try the UDT with that code, is it still faster than separate arrays?
                On my machine using the new tests are 1.3 faster using separate arrays vs 2-dimensional. Also separate arrays are 1.11x faster than udt.

                What I meant to show there is that three separate arrays allow different type dimensioning for each array, hence another opportunity for optimization. The two dimensional array is locked into one type.
                This is one of the reason I checked a udt. Each value can be a different type in the udt.

                The performance difference, +/- 10, %leaves the option to personal coding preference.

                Code:
                #COMPILE EXE
                #DIM ALL
                #INCLUDE "win32api.inc"
                
                TYPE udtType
                    a AS SINGLE
                    b AS SINGLE
                    c AS SINGLE
                END TYPE
                
                FUNCTION PBMAIN () AS LONG
                    DIM a(1000) AS SINGLE, b(1000) AS SINGLE, c(1000) AS SINGLE
                    DIM abc2(2, 1000) AS SINGLE
                    DIM udt(1000) AS udtType
                    DIM tUdt AS udtType
                
                    LOCAL q1, q2 AS QUAD, ii, ii2 AS LONG
                
                    FOR ii = 0 TO 1000
                       abc2(0, ii) = ii
                       abc2(1, ii) = ii
                       abc2(2, ii) = ii
                       a(ii) = ii
                       b(ii) = ii
                       c(ii) = ii
                       udt(ii).a = ii
                       udt(ii).b = ii
                       udt(ii).c = ii
                    NEXT
                
                    queryPerformanceCounter(q1)
                
                    FOR ii2 = 1 TO 1000
                    FOR ii = 0 TO 1000
                       IF A(ii) = ii AND B(ii) = ii AND C(ii) = ii THEN    '<< this method was approx 1.6x faster on my machine
                         !nop
                       END IF
                    NEXT
                    NEXT
                    queryPerformanceCounter(q2)
                    ? STR$(q2 - q1)
                    queryPerformanceCounter(q1)
                    FOR ii2 = 1 TO 1000
                    FOR ii = 0 TO 1000
                       IF abc2(0, ii) = ii AND abc2(1, ii) = ii AND abc2(2, ii) = ii THEN
                         !nop
                       END IF
                    NEXT
                    NEXT
                    queryPerformanceCounter(q2)
                    ? STR$(q2 - q1)
                
                
                    queryPerformanceCounter(q1)
                    FOR ii2 = 1 TO 1000
                    FOR ii = 0 TO 1000
                       IF udt(ii).a = ii AND udt(ii).b = ii AND udt(ii).c = ii THEN
                         !nop
                       END IF
                    NEXT
                    NEXT
                    queryPerformanceCounter(q2)
                    ? STR$(q2 - q1)
                
                END FUNCTION

                Comment

                Working...
                X