Announcement

Collapse
No announcement yet.

Possible to copy an ARRAY with VARPTR() ?

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

  • #21
    Isn't that a fine kettle of fish!
    Offer a suggestion, go away for 10 hours, come back and there's six or so solutions all better than mine. Well!!

    Now Christopher has a weer problem, figuring out which solution suits him best thus showing that the answer to a problem is indeed another problem.
    And it shouldn't be any other way!
    Well done, folks!!
    Rod
    In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

    Comment


    • #22
      Here is a test and a benchmark on copying one integer array to another. It uses about 1.6 gig of memory with both memory buffers and on my legacy i7, just under 100 ms. Now while this is done with DWORD 32 bit integers, it can be used with any data type, as long as you know the data size in bytes, BYTE WORD DWORD QWORD XMMWORD, PB does not natively support YMMWORD.
      Code:
      ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      
          #include "\basic\include\win32api.inc"
      
          MACRO iter = 200000000
      
      ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      
      FUNCTION PBmain as LONG
      
          LOCAL parr1 as DWORD
          LOCAL parr2 as DWORD
          LOCAL larr1 as DWORD
          LOCAL tcnt as DWORD
          LOCAL cntr as DWORD
          LOCAL numb as DWORD
      
          DIM iArr1(iter) as DWORD
          DIM iArr2(iter) as DWORD
      
        ' ------------------------------
        ' fill array with numbers
        ' ------------------------------
          cntr = 0
          numb = 999999
      
        lp:
          iarr1(cntr) = numb
          ! add cntr, 1
          ! sub numb, 1
          ! mov eax, cntr
          ! cmp eax, iter
          ! jbe lp
      
        ' ------------------------------
      
          parr1 = VarPtr(iArr1(0))
          parr2 = VarPtr(iArr2(0))
      
          StdOut format$(parr1)+" "+format$(parr2)
      
          larr1 = iter*4
      
        ' --------------------------------------
          tcnt = GetTickCount
      
          bcopy parr1,parr2,larr1
      
          tcnt = GetTickCount - tcnt
        ' --------------------------------------
      
          cntr = 0
        lbl:
          StdOut format$(iarr2(cntr))
          ! add cntr, 1
          ! mov eax, cntr
          ! cmp eax, 1000
          ! jbe lbl
      
          StdOut "Done in "+format$(tcnt)+" ms"
      
          waitkey$
      
          erase iArr1
          erase iArr2
      
      End FUNCTION
      
      ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      
      FUNCTION bcopy(ByVal src as DWORD,ByVal dst as DWORD,ByVal bcount as DWORD) as DWORD
      
          #REGISTER NONE
      
          ! mov esi, src
          ! mov edi, dst
          ! mov ecx, bcount
          ! rep movsb
      
      End FUNCTION
      
      ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      hutch at movsd dot com
      The MASM Forum - SLL Modules and PB Libraries

      http://www.masm32.com/board/index.php?board=69.0

      Comment


      • #23
        Very nice, Steve. Did you try the same using MAT iArr2 = iArr1? I remember doing some tests long ago and found that nothing could beat Bob's code in both speed and simplicity to use. As it often has been over the years..

        Comment


        • #24
          Knowing the data are contiguous you can use the intrinsic array information functions to get the info you need to copy the data from one place to another.

          Start of data = VARPTR (LBOUND(array), 1) [ LBOUND (Array, 2)[ [ as many dimensions as exist, which is ARRAYATTR (arrray(), 3)])
          Length of data = ARRAYATTR(array(),3) * ARRAYATTR (array(),4) ==> Number of elements * element size

          But for string (and variant, and interface) arrays, copying the data gets pointers copied only and the data are not duplicated.

          But as is my habit, let's ask the question.. what are you trying to accomplish that you think copying (reference or data?) an entire array is the solution? Maybe there is "a better way." (Maybe not, but asking costs nothing!)

          MCM
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #25
            Although I don't believe it will perform better than Hutch's ASM, you can consider using POKE$ to copy array to array. In a single (longish) line of PB code.

            POKE$ VARPTR(ArrayDst(0, 0, 0)), PEEK$(VARPTR(ArraySrc(0, 0, 0)), (UBOUND(ArraySrc(1)) + 1) * (UBOUND(ArraySrc(2)) + 1) * (UBOUND(ArraySrc(3)) + 1) * SIZEOF(ArrayType))

            [Obviously, would need to modify the above if Array LBOUND <> 0. But as Michael would doubtless tell you, if your LBOUNDs aren't 0 then you're doing arrays wrong... ]

            Comment


            • #26
              Awesome Steve

              Can you do it with string arrays for your codes in post #22?

              Comment


              • #27
                Hi Anne,

                Sad to say it does not work on basic dynamic string for a couple of reasons, string data can be variable length and in the case of basic dynamic string, each string is a different memory allocation.

                You could look at the array of pointers that basic uses to identify the string array members but I doubt you would get any real speed gains as you still must copy each array member to the other array member.

                Basic string has the advantage of flexibility but that flexibility comes at the cost of complexity, you would have to use other far cruder techniques to be able to use linear copy code.
                hutch at movsd dot com
                The MASM Forum - SLL Modules and PB Libraries

                http://www.masm32.com/board/index.php?board=69.0

                Comment


                • #28
                  Can you do it with string arrays for your codes in post #22?
                  As Mr. Hutchesson has pointed out, no you can't, BUT... what if you changed your Array to be an array of FIXED-SIZE strings? Then you could do something similar. It will cost you memory and maybe some additional coding elsewhere..but since your app is not described I don't know if it's worth it so I can only go so far as to say, "It's a thought"

                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #29
                    Fixed

                    Here is a safe version of copy array, it is fast as Mat or any ASM so far (the demo shows this is a tie for all methods, each one is copying same amount of bytes ). There is no penalty to speak of checking size, just more typing.

                    Element Size is the size of the fixed string length. If you use it on numeric array the Element would be the pointer size Example DWORD is four wide, a byte is one wide.

                    This should stop the classic buffer overrun, it still can happen if you provide the wrong element sizes.

                    Code:
                    #COMPILE EXE
                    #DIM ALL
                    'use CC
                    #INCLUDE "Win32api.inc"
                    
                    MACRO iter = 200000000
                    
                    FUNCTION PBSafeArrayCopy (BYVAL pSrc AS DWORD, BYVAL pDest AS DWORD, BYVAL nScrSize AS LONG, _
                                            BYVAL nDestSize AS LONG, BYVAL nScrElementSize AS LONG, BYVAL nDestElementSize AS LONG) AS LONG
                    
                               IF nscrSize <> nDestSize THEN FUNCTION = 1 :EXIT FUNCTION  :
                               IF nScrElementSize <> nDestElementSize THEN FUNCTION = 2  : EXIT FUNCTION
                    
                               CopyMemory  pDest, pSrc, (nDestSize * nDestElementSize)   ' rtl
                               FUNCTION = 0
                               ' error 1 sorce destination size do not match
                               ' error 2 string size or type mismatch
                               '0 no error
                    END FUNCTION
                    
                    
                    
                    
                    FUNCTION PBMAIN () AS LONG
                    
                     LOCAL Loopi AS LONG
                     FOR Loopi = 1 TO 4
                     dwdd
                     matt_
                     sa
                     sh
                    
                    
                     STDOUT "Round "  + STR$ (Loopi) +   " Finished !"
                     NEXT
                     STDOUT
                     STDOUT "Done Get a Fork !"
                     WAITKEY$
                    END FUNCTION
                    
                    
                    
                    SUB sa ()
                            DIM org(799999) AS STRING * 1000
                            DIM cpy(799999) AS STRING * 1000
                            LOCAL nx AS LONG
                            LOCAL szTxt AS STRINGZ * 1000
                            LOCAL tcnt AS DWORD
                            LOCAL nRet AS LONG
                                      szTxt = STRING$(970,"-")
                    
                                      FOR nx = 0 TO 799999
                                         org(nx)= szTxt + " Test String Number "  + STR$(nx)
                                      NEXT x
                    
                    
                                      tcnt = GetTickCount
                    
                                            nRet = PBSafeArrayCopy ( VARPTR (org(0)), VARPTR(cpy(0)), ARRAYATTR(org(),4), ARRAYATTR(cpy(),4), 1000, 1000 )
                    
                                            IF nret THEN  ? "Array Size Mismatch" : EXIT SUB
                    
                                      tcnt = GetTickCount - tcnt
                    
                    
                                      STDOUT "String Done in "+FORMAT$(tcnt)+" ms"
                    
                    
                                      ERASE  org
                                      ERASE  cpy
                    
                    END SUB
                    
                    SUB dwdd ()
                    
                    
                            DIM org(iter) AS  DWORD
                            DIM cpy(iter) AS  DWORD
                            LOCAL nx AS LONG
                            LOCAL tcnt AS DWORD
                            LOCAL nRet AS LONG
                    
                                      FOR nx = 0 TO 200000000
                                         org(nx)=  nx
                                      NEXT x
                    
                                      tcnt = GetTickCount
                                                                                                                            'dword size is 4 bytes wide
                                      nret = PBSafeArrayCopy ( VARPTR (org(0)), VARPTR(cpy(0)), (ARRAYATTR(org(),4)), (ARRAYATTR(cpy(),4)), 4, 4)
                    
                                      IF nret THEN  ? "Array Size Mismatch" : EXIT SUB
                    
                                      tcnt = GetTickCount - tcnt
                    
                                         STDOUT "Dword  Done in "+FORMAT$(tcnt)+" ms"
                    
                                   ERASE  org
                                   ERASE  cpy
                    
                    END SUB
                    
                    SUB matt_   ()
                    
                            DIM org(iter) AS  DWORD         'iter  * 4
                            DIM cpy(iter) AS  DWORD
                            LOCAL nx AS LONG
                    
                            LOCAL tcnt AS DWORD
                    
                    
                                     FOR nx = 0 TO iter
                                         org(nx)=  nx
                                     NEXT x
                    
                                     tcnt = GetTickCount
                    
                                     MAT cpy () = org()
                    
                                     tcnt = GetTickCount - tcnt
                    
                                     STDOUT "Mat    Done in "+FORMAT$(tcnt)+" ms"
                    
                                   ERASE  org
                                   ERASE  cpy
                    END SUB
                    
                    
                    
                    
                    FUNCTION sh AS LONG       'steves  asm
                    
                        LOCAL parr1 AS DWORD
                        LOCAL parr2 AS DWORD
                        LOCAL larr1 AS DWORD
                        LOCAL tcnt AS DWORD
                        LOCAL cntr AS DWORD
                        LOCAL numb AS DWORD
                    
                        DIM iArr1(iter) AS DWORD
                        DIM iArr2(iter) AS DWORD
                    
                      ' ------------------------------
                      ' fill array with numbers
                      ' ------------------------------
                        cntr = 0
                        numb = 999999
                    
                      lp:
                        iarr1(cntr) = numb
                        ! add cntr, 1
                        ! sub numb, 1
                        ! mov eax, cntr
                        ! cmp eax, iter
                        ! jbe lp
                    
                      ' ------------------------------
                    
                        parr1 = VARPTR(iArr1(0))
                        parr2 = VARPTR(iArr2(0))
                    
                       ' StdOut format$(parr1)+" "+format$(parr2)
                    
                        larr1 = iter*4
                    
                      ' --------------------------------------
                        tcnt = GetTickCount
                    
                        bcopy parr1,parr2,larr1
                    
                        tcnt = GetTickCount - tcnt
                      ' --------------------------------------
                    
                        cntr = 0
                      lbl:
                    '    StdOut format$(iarr2(cntr))
                        ! add cntr, 1
                        ! mov eax, cntr
                        ! cmp eax, 1000
                        ! jbe lbl
                    
                         STDOUT "ASM    Done in "+FORMAT$(tcnt)+" ms"
                    
                    
                        ERASE iArr1
                        ERASE iArr2
                    
                    END FUNCTION
                    
                    ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                    
                    FUNCTION bcopy(BYVAL src AS DWORD,BYVAL dst AS DWORD,BYVAL bcount AS DWORD) AS DWORD
                    
                        #REGISTER NONE
                    
                        ! mov esi, src
                        ! mov edi, dst
                        ! mov ecx, bcount
                        ! rep movsb
                    
                    END FUNCTION
                    Last edited by Michael Mayerhoffer; 1 Oct 2021, 12:03 PM.
                    A dozen what.

                    Comment


                    • #30
                      Hi Mike,

                      Great result, compliments on creative genius.
                      hutch at movsd dot com
                      The MASM Forum - SLL Modules and PB Libraries

                      http://www.masm32.com/board/index.php?board=69.0

                      Comment


                      • #31
                        This does not work and no error is returned
                        EXIT FUNCTION would also be executed before setting the function error number.
                        Guessing this is not the code be tested.
                        Code:
                        #INCLUDE "Win32api.inc"
                        FUNCTION PBSafeArrayCopy (BYVAL pSrc AS DWORD, BYVAL pDest AS DWORD, BYVAL nScrSize AS LONG, _
                         BYVAL nDestSize AS LONG, BYVAL nScrElementSize AS LONG, BYVAL nDestElementSize AS LONG) AS LONG
                         IF nscrSize <> nDestSize THEN EXIT FUNCTION  : FUNCTION = 1 'wrong
                         IF nScrElementSize <> nDestElementSize THEN EXIT FUNCTION  : FUNCTION = 2 'wrong
                         CopyMemory  pDest, pSrc, (nDestSize * nDestElementSize)   ' rtl
                         FUNCTION = 0
                         ' error 1 sorce destination size do not match
                         ' error 2 string size or type mismatch
                         '0 no error
                        END FUNCTION
                        
                        FUNCTION PBMAIN () AS LONG
                         LOCAL nx   AS LONG
                         LOCAL nret AS LONG
                         DIM org(0 TO 2) AS STRING * 10
                         DIM cpy(0 TO 2) AS STRING * 10
                         FOR nx = 0 TO 2
                          org(nx)= "Test "+ STR$(nx)
                         NEXT
                         nret=PBSafeArrayCopy (VARPTR(org(0)),VARPTR(cpy(0)),(ARRAYATTR(org(),4)),(ARRAYATTR(cpy(),4)),4,4)
                         IF nret = 0 THEN
                          FOR nx = 0 TO 2
                           ? cpy(nx)
                          NEXT
                         END IF
                        END FUNCTION


                        Code:
                        'Thanks, Rod and Stuart for this
                        MACRO CopyArray(A1, A2) = PARSE JOIN$ (a1,BINARY), a2, BINARY
                        FUNCTION PBMAIN () AS LONG
                         LOCAL nx   AS LONG
                         DIM org(0 TO 2) AS STRING * 10
                         DIM cpy(0 TO 2) AS STRING * 10
                         FOR nx = 0 TO 2
                          org(nx)= "Test "+ STR$(nx)
                         NEXT
                         CopyArray(org(),cpy())
                         ? JOIN$(cpy(),$CR)
                        END FUNCTION
                        The world is full of apathy, but who cares?

                        Comment


                        • #32
                          I have an algo somewhere that reads a text file into an array of pointers and it is genuinely fast as it scans through a text file and converts the CRLF into an ascii 0 and stores each pointer into a pointer array but in that form you cannot extend the string as it is still linear memory. For a string array, it depends on what you want to do, if you need the flexibility of basic dynamic string where each string is a separate allocation as is normal with basic dynamic string, you cannot use a linear read/write technique.

                          Now in the ordinary sense, something as crude as a(0) = b(0) involves reading and writing the string so it would be worth properly timing an array copy of this technology and simply increase the array index until you got to the end of the array.
                          Code:
                          ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                          
                              #include "\basic\include\win32api.inc"
                          
                          ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                          
                          FUNCTION PBmain as LONG
                          
                              LOCAL lcnt as DWORD
                              LOCAL numb as DWORD
                              LOCAL tcnt as DWORD
                          
                              DIM a(10000000) as STRING
                              DIM b(10000000) as STRING
                          
                              lcnt = 0
                              numb = 100000
                          
                            lbl0:
                              a(lcnt) = str$(100000000)    ' write number string to "a" array
                              ! sub numb, 1
                              ! add lcnt, 1
                              ! cmp lcnt, 10000000
                              ! jb lbl0
                          
                              lcnt = 0
                          
                              tcnt = GetTickCount
                          
                            lbl:
                              b(lcnt) = a(lcnt)           ' copy "a" array to "b" array
                              ! add lcnt, 1
                              ! cmp lcnt, 10000000
                              ! jb lbl
                          
                              tcnt = GetTickCount - tcnt
                          
                              StdOut format$(tcnt)
                              waitkey$
                          
                          End FUNCTION
                          
                          ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                          hutch at movsd dot com
                          The MASM Forum - SLL Modules and PB Libraries

                          http://www.masm32.com/board/index.php?board=69.0

                          Comment


                          • #33
                            Mike , Thanks for catching that.




                            A dozen what.

                            Comment


                            • #34
                              ?

                              Code:
                              #COMPILE EXE
                              #DIM ALL
                              'use CC
                              #INCLUDE "Win32api.inc"
                              
                              
                              FUNCTION PBMAIN () AS LONG
                              
                              
                               mc
                              
                              
                              END FUNCTION
                              
                              
                              
                              
                              
                                MACRO CopyArray(A1, A2) = PARSE JOIN$ (a1,BINARY), a2, BINARY
                              
                              FUNCTION mc () AS LONG
                              
                                      DIM org(799999) AS STRING * 1000
                                      DIM cpy(799999) AS STRING * 1000
                                      LOCAL nx AS LONG
                                      LOCAL szTxt AS STRINGZ * 1000
                                      LOCAL tcnt AS DWORD
                                      LOCAL nRet AS LONG
                              
                              
                                                FOR nx = 0 TO 799999
                                                   org(nx)= " Where is Test String Number "  + STR$(nx)
                                                NEXT x
                              
                                                tcnt = GetTickCount
                              
                                                CopyArray(org(),cpy())
                              
                                                tcnt = GetTickCount - tcnt
                              
                                                STDOUT "mc  Done in "+FORMAT$(tcnt)+ "?"
                              
                                                ? cpy(799999 )
                              
                              
                                             ERASE  org
                                             ERASE  cpy
                                          WAITKEY$
                              END FUNCTION
                              A dozen what.

                              Comment


                              • #35
                                Hutch Thanks,

                                your code, you speak of, is on the Forum here I believe.
                                A dozen what.

                                Comment


                                • #36
                                  Summarized code, pretty slick.
                                  Code:
                                  #INCLUDE "win32api.inc"
                                  %len=1000
                                  FUNCTION PBMAIN () AS LONG
                                   REDIM a(0 TO 12345)  AS STRINGZ * %len
                                   REDIM b(0 TO 12345)  AS STRINGZ * %len
                                   a(0)         = "First element"
                                   a(12345)     = "Last element"
                                   CopyMemory  VARPTR(b(0)), VARPTR(a(0)), ARRAYATTR(a(),4)*%len
                                  END FUNCTION

                                  The world is full of apathy, but who cares?

                                  Comment


                                  • #37
                                    My is fixed.










                                    Code:
                                    #COMPILE EXE
                                    #DIM ALL
                                    'use CC
                                    #INCLUDE "Win32api.inc"
                                    
                                    MACRO iter = 200000000
                                    
                                    FUNCTION PBSafeArrayCopy (BYVAL pSrc AS DWORD, BYVAL pDest AS DWORD, BYVAL nScrSize AS LONG, _
                                                            BYVAL nDestSize AS LONG, BYVAL nScrElementSize AS LONG, BYVAL nDestElementSize AS LONG) AS LONG
                                    
                                               IF nscrSize <> nDestSize THEN  FUNCTION = 1  : EXIT FUNCTION
                                               IF nScrElementSize <> nDestElementSize THEN  FUNCTION = 2  : EXIT FUNCTION
                                    
                                               CopyMemory  pDest, pSrc, (nDestSize * nDestElementSize)   ' rtl
                                               FUNCTION = 0
                                               ' error 1 sorce destination size do not match
                                               ' error 2 string size or type mismatch
                                               '0 no error
                                    END FUNCTION
                                    
                                    
                                    
                                    
                                    FUNCTION PBMAIN () AS LONG
                                    
                                     LOCAL Loopi AS LONG
                                     FOR Loopi = 1 TO 4
                                    
                                      sa
                                     
                                      mc
                                    
                                     STDOUT "Round "  + STR$ (Loopi) +   " Finished !"
                                     NEXT
                                     STDOUT
                                     STDOUT "Done Get a Fork !"
                                     WAITKEY$
                                    END FUNCTION
                                    
                                    
                                    
                                    SUB sa ()
                                            DIM org(799999) AS STRING * 1000
                                            DIM cpy(799999) AS STRING * 1000
                                            LOCAL nx AS LONG
                                            LOCAL szTxt AS STRINGZ * 1000
                                            LOCAL tcnt AS DWORD
                                            LOCAL nRet AS LONG
                                                      szTxt = STRING$(970,"-")
                                    
                                                      FOR nx = 0 TO 799999
                                                         org(nx)= szTxt + " Test String Number "  + STR$(nx)
                                                      NEXT x
                                    
                                    
                                                      tcnt = GetTickCount
                                    
                                                            nRet = PBSafeArrayCopy ( VARPTR (org(0)), VARPTR(cpy(0)), ARRAYATTR(org(),4), ARRAYATTR(cpy(),4), 1000, 1000 )
                                    
                                                            IF nret THEN  ? "Array Size Mismatch" : EXIT SUB
                                    
                                                      tcnt = GetTickCount - tcnt
                                    
                                    
                                                      STDOUT "String Done in "+FORMAT$(tcnt)+" ms"
                                    
                                                      STDOUT  cpy(799999)
                                                      ERASE  org
                                                      ERASE  cpy
                                    
                                    END SUB
                                    
                                    
                                     MACRO CopyArray(A1, A2) = PARSE JOIN$ (a1,BINARY), a2, BINARY
                                    
                                    FUNCTION mc () AS LONG
                                    
                                            DIM org(799999) AS STRING * 1000
                                            DIM cpy(799999) AS STRING * 1000
                                            LOCAL nx AS LONG
                                            LOCAL szTxt AS STRINGZ * 1000
                                            LOCAL tcnt AS DWORD
                                            LOCAL nRet AS LONG
                                    
                                    
                                                      FOR nx = 0 TO 799999
                                                         org(nx)= " Where is Test String Number "  + STR$(nx)
                                                      NEXT x
                                    
                                                      tcnt = GetTickCount
                                    
                                                      CopyArray(org(),cpy())
                                    
                                                      tcnt = GetTickCount - tcnt
                                    
                                                      STDOUT "mc  Done in "+FORMAT$(tcnt)+ "?"
                                    
                                                      ? cpy(799999 )
                                    
                                    
                                                   ERASE  org
                                                   ERASE  cpy
                                                WAITKEY$
                                    END FUNCTION
                                    A dozen what.

                                    Comment


                                    • #38
                                      Mike LOL "slick"

                                      The code I posted was tested and some , unfortunately , posted it piece by piece to many things in there. Somewhere I miscopied or pasted out of order. My Bad I own up to it.

                                      I am pretty sure some code here was not well test.
                                      A dozen what.

                                      Comment


                                      • #39
                                        Mike,

                                        The last one I posted was testing string assignment, it was different to the integer array copy done with "rep movsb".

                                        I forgot to put the variable into the source array but for the task of filling each source array with a string, it did the job. There is no timing difference using the variable but am posting the correction below.
                                        Code:
                                        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                        
                                            #include "\basic\include\win32api.inc"
                                        
                                        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                        
                                        FUNCTION PBmain as LONG
                                        
                                            LOCAL lcnt as DWORD
                                            LOCAL numb as DWORD
                                            LOCAL tcnt as DWORD
                                        
                                            DIM a(10000000) as STRING
                                            DIM b(10000000) as STRING
                                        
                                            lcnt = 0
                                            numb = 100000
                                        
                                          lbl0:
                                            a(lcnt) = str$(numb)        ' write number string to "a" array
                                            ! sub numb, 1
                                            ! add lcnt, 1
                                            ! cmp lcnt, 10000000
                                            ! jb lbl0
                                        
                                            lcnt = 0
                                        
                                            tcnt = GetTickCount
                                        
                                          lbl:
                                            b(lcnt) = a(lcnt)           ' copy "a" array to "b" array
                                            ! add lcnt, 1
                                            ! cmp lcnt, 10000000
                                            ! jb lbl
                                        
                                            tcnt = GetTickCount - tcnt
                                        
                                            StdOut format$(tcnt)
                                            waitkey$
                                        
                                        End FUNCTION
                                        
                                        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                        hutch at movsd dot com
                                        The MASM Forum - SLL Modules and PB Libraries

                                        http://www.masm32.com/board/index.php?board=69.0

                                        Comment


                                        • #40
                                          Originally posted by Michael Mayerhoffer View Post
                                          ?

                                          Code:
                                          ...
                                          
                                          MACRO CopyArray(A1, A2) = PARSE JOIN$ (a1,BINARY), a2, BINARY
                                          ...
                                          DIM org(799999) AS STRING * 1000
                                          DIM cpy(799999) AS STRING * 1000
                                          If you're going to waste all that space by using 800,000 x 1000 character fixed length strings to store strings which have a maximum length of 32 characters, you will need to use #OPTION LARGEMEM32
                                          II you use ordinary dynamic STRINGs instead, you don't need it.

                                          Using dynamic string arrays with the macro gives about the same time as your PBSafeArrayCopy with the bloated arrays
                                          (And you don't need a bunch of different functions for different type of arrays - the macro works "out of the box" for any variable type)

                                          Comment

                                          Working...
                                          X