### Author Topic: Copying arrays FOR vs _MEMCOPY  (Read 168 times)

#### TempodiBasic

##### Copying arrays FOR vs _MEMCOPY
« on: July 08, 2018, 06:44:58 PM »
Hi Guys

Learning  _MEM and its cousins _MEM() _MEMPUT _MEMGET _MEMCOPY _MEMNEW etc etc
seeing how to make a copy of array1 into array2 and following Steve's Wiki instructions
i wrote this code...
but on my TOSHIBA the time that I get is the same with the two methods, while surely the code more simple is _MEM.
Here the code
Code: [Select]
`DIM a(100, 100) AS INTEGERDIM b(100, 100) AS INTEGERPRINT " COPY Array by FOR"oldt1 = TIMERSLEEP 2initazshowarraySLEEP 2copyArrayForshowarraySLEEP 2oldt1 = TIMER - oldt1PRINT oldt1SLEEP 4PRINT " COPY Array by _MEMCOPY"oldt2 = TIMERSLEEP 2initazshowarraySLEEP 2CopyArrayMEMshowarraySLEEP 2oldt2 = TIMER - oldt2PRINT oldt2SLEEP 2PRINT "CopyFor = "; oldt1; " Copy_MEM = "; oldt2ENDSUB initaz    SHARED a() AS INTEGER, b() AS INTEGER    '--INITIALIZTION    PRINT "INITALIZATION"    FOR i1 = 0 TO 100        FOR i2 = 0 TO 100            b(i1, i2) = i1            a(i1, i2) = 999        NEXT    NEXTEND SUBSUB showarray    SHARED a() AS INTEGER, b() AS INTEGER    PRINT "SHOWING ARRAYS  B   A "    FOR i1 = 0 TO 100        FOR i2 = 0 TO 100            PRINT b(i1, i2), a(i1, i2)        NEXT    NEXTEND SUBSUB copyArrayFor    SHARED a() AS INTEGER, b() AS INTEGER    'copy array a to array b one index at a time:    'FOR...NEXT|    FOR i1 = 0 TO 100        'FOR...NEXT|        FOR i2 = 0 TO 100            b(i1, i2) = a(i1, i2)        NEXT    NEXTEND SUBSUB CopyArrayMEM    SHARED a() AS INTEGER, b() AS INTEGER    'copy array a to array b in memory instantly:    DIM ma AS _MEM: ma = _MEM(a()) 'place array data into blocks    DIM mb AS _MEM: mb = _MEM(b())    _MEMCOPY ma, ma.OFFSET, ma.SIZE TO mb, mb.OFFSET    _MEMFREE ma: _MEMFREE mb 'clear the memory when doneEND SUB`
Well, surely there is a better code to use _MEM. But How?

#### SMcNeill

• QB64 Developer
##### Re: Copying arrays FOR vs _MEMCOPY
« Reply #1 on: July 08, 2018, 08:00:10 PM »
The problem here isn't in the copying routines; the problem is with the method used to time the copying...

Lots of SLEEP statements, along with the initialization of the first array, and then printing to the screen... All these things take up time which makes it hard to see what, if any, change the switch from FOR to _MEMCOPY does for your program.

Taking the SLEEP, initialize, and PRINT statements out, and just timing the copy routines themselves, and changing the routines to work off a larger loop limit to highlight the differences, and what we see is the following:

Code: [Select]
`CONST TestLimit = 10000DIM a(TestLimit, TestLimit) AS INTEGERDIM b(TestLimit, TestLimit) AS INTEGERDIM SHARED ma1 AS _MEMDIM SHARED mb1 AS _MEMPRINT " COPY Array by FOR"initazoldt1 = TIMER(0.001)copyArrayFor'showarrayoldt1 = TIMER(0.001) - oldt1PRINT oldt1PRINT " COPY Array by _MEMCOPY"initazoldt2 = TIMER(0.001)CopyArrayMEM'showarrayoldt2 = TIMER(0.001) - oldt2PRINT oldt2PRINT "CopyFor = "; oldt1; " Copy_MEM = "; oldt2ENDSUB initaz    SHARED a() AS INTEGER, b() AS INTEGER    '--INITIALIZTION    PRINT "INITALIZATION"    FOR i1 = 0 TO TestLimit        FOR i2 = 0 TO TestLimit            b(i1, i2) = i1            a(i1, i2) = 999        NEXT    NEXTEND SUBSUB showarray    SHARED a() AS INTEGER, b() AS INTEGER    PRINT "SHOWING ARRAYS  B   A "    FOR i1 = 0 TO TestLimit        FOR i2 = 0 TO TestLimit            PRINT b(i1, i2), a(i1, i2)        NEXT    NEXTEND SUBSUB copyArrayFor    SHARED a() AS INTEGER, b() AS INTEGER    'copy array a to array b one index at a time:    'FOR...NEXT|    FOR i1 = 0 TO TestLimit        'FOR...NEXT|        FOR i2 = 0 TO TestLimit            b(i1, i2) = a(i1, i2)        NEXT    NEXTEND SUBSUB CopyArrayMEM    SHARED a() AS INTEGER, b() AS INTEGER    'copy array a to array b in memory instantly:    DIM ma AS _MEM: ma = _MEM(a()) 'place array data into blocks    DIM mb AS _MEM: mb = _MEM(b())    _MEMCOPY ma, ma.OFFSET, ma.SIZE TO mb, mb.OFFSET    _MEMFREE ma: _MEMFREE mb 'clear the memory when doneEND SUB`
7.7 seconds for the FOR LOOP to copy the arrays.
0.03 seconds for the _MEMCOPY to do its thing.

I think that shows a good comparison of which one might be a little more faster for our programs.

#### TempodiBasic

##### Re: Copying arrays FOR vs _MEMCOPY
« Reply #2 on: July 09, 2018, 07:43:26 AM »
Thanks Steve

I must agree with you that I have done a SLEEPed use of _MEM...
:-)
IMHO the whole structure of code wins over single instructions

Thanks again

#### TempodiBasic

##### Re: Copying arrays FOR vs _MEMCOPY
« Reply #3 on: July 09, 2018, 09:29:25 PM »
Hi Steve

agreeing about the speedy of _MEM and the slowness of FOR...NEXT
here I post a code to show the one situation on which I think coders must prefer FOR...NEXT to _MEM
Code: [Select]
`OPTION BASE 1REDIM a(5, 3) AS INTEGERDIM b(UBOUND(a, 1), UBOUND(a, 2)) AS INTEGERinitazPRINT "Array A  ";showarray a()PRINT " Array B  ";showarray b()SLEEP 2PRINT "Saving orginal array data "copyArray a(), b()showarray b()PRINT "press a key";: SLEEP: CLSPRINT " REDIM array A with _PRESERVE  "REDIM _PRESERVE a(7, 6) AS INTEGERshowarray a()showarray b()PRINT "Restoring original array data into array A "copyArray b(), a()showarray a()PRINT " Garbage by _PRESERVE feature "PRINT "press a key";: SLEEP: CLS' to fix _PRESERVE  we must not use _PRESERVEPRINT " Redim Array A and NO _preserve "REDIM a(8, 7) AS INTEGERshowarray a()showarray b()' no clear no erase because they take down dimensions of the arrayPRINT " Restoring original array data into array A "copyArray b(), a()showarray a()showarray b()PRINT "Press a key ": SLEEP: CLSPRINT " Now Redim A with NO _PRESERVE"REDIM a(7, 6) AS INTEGERshowarray a()showarray b()PRINT " Restoring data using CopyArrayFOR "CopyArrayFor b(), a()showarray a()showarray b()ENDSUB initaz    SHARED a() AS INTEGER, b() AS INTEGER    '--INITIALIZATION    PRINT "INITIALIZATION"    FOR i1 = 1 TO UBOUND(a, 1)        FOR i2 = 1 TO UBOUND(a, 2)            b(i1, i2) = 999            a(i1, i2) = i1        NEXT    NEXTEND SUBSUB showarray (al() AS INTEGER)    PRINT "SHOWING ARRAYS  "    FOR i1 = 1 TO UBOUND(al, 1)        FOR i2 = 1 TO UBOUND(al, 2)            PRINT al(i1, i2); "-";        NEXT        _DELAY .5        PRINT    NEXT    PRINTEND SUBSUB copyArray (S() AS INTEGER, D() AS INTEGER)    ' COPYARRAY (ArraySource(), ArrayDest())    'copy array a1 to array b1 using _MEM functions:    PRINT " COPYING ARRAY..."    DIM mD AS _MEM, mS AS _MEM    mD = _MEM(D())    mS = _MEM(S())    ' _MEMPUT mD, mD.OFFSET, S()  ' ALSO THIS INSTRUCTION GIVES THE SAME RESULTS....    _MEMCOPY mS, mS.OFFSET, mS.SIZE TO mD, mD.OFFSET    _MEMFREE mD: _MEMFREE mS    PRINT "END COPY!"END SUBSUB CopyArrayFor (S() AS INTEGER, D() AS INTEGER)    '-- COPY ARRAY USING FOR CICLES    PRINT "COPY ARRAY USING FOR CICLES"    FOR i1 = 1 TO UBOUND(s, 1)        FOR i2 = 1 TO UBOUND(s, 2)            D(i1, i2) = S(i1, i2)        NEXT    NEXTEND SUB`This code try to solve _PRESERVE issue using a manual function of copy and paste of old array in new array.
here _delay and SLEEP are used to show output, no speed of performance but rightness of results of operations of code is the cutoff to choose method to copy array....

seeing how _MEM is fast I wish that it is again a my poor code structure to give me these results...but it seems that _MEM instructions duplicate _PRESERVE results.