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

#### TempodiBasic

##### Copying arrays FOR vs _MEMCOPY
« on: July 08, 2018, 05: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 INTEGER
DIM b(100, 100) AS INTEGER

PRINT " COPY Array by FOR"
oldt1 = TIMER
SLEEP 2
initaz
showarray
SLEEP 2
copyArrayFor
showarray
SLEEP 2
oldt1 = TIMER - oldt1
PRINT oldt1
SLEEP 4
PRINT " COPY Array by _MEMCOPY"
oldt2 = TIMER
SLEEP 2
initaz
showarray
SLEEP 2
CopyArrayMEM
showarray
SLEEP 2
oldt2 = TIMER - oldt2
PRINT oldt2
SLEEP 2
PRINT "CopyFor = "; oldt1; " Copy_MEM = "; oldt2
END

SUB 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
NEXT
END SUB

SUB 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
NEXT
END SUB

SUB 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
NEXT
END SUB

SUB 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 done
END 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, 07: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 = 10000
DIM a(TestLimit, TestLimit) AS INTEGER
DIM b(TestLimit, TestLimit) AS INTEGER
DIM SHARED ma1 AS _MEM
DIM SHARED mb1 AS _MEM

PRINT " COPY Array by FOR"
initaz
oldt1 = TIMER(0.001)
copyArrayFor
'showarray
oldt1 = TIMER(0.001) - oldt1
PRINT oldt1

PRINT " COPY Array by _MEMCOPY"
initaz
oldt2 = TIMER(0.001)
CopyArrayMEM
'showarray
oldt2 = TIMER(0.001) - oldt2
PRINT oldt2

PRINT "CopyFor = "; oldt1; " Copy_MEM = "; oldt2

END

SUB 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
NEXT
END SUB

SUB 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
NEXT
END SUB

SUB 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
NEXT
END SUB

SUB 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 done
END 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, 06: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, 08: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 1
REDIM a(5, 3) AS INTEGER
DIM b(UBOUND(a, 1), UBOUND(a, 2)) AS INTEGER

initaz
PRINT "Array A  ";
showarray a()
PRINT " Array B  ";
showarray b()
SLEEP 2
PRINT "Saving orginal array data "
copyArray a(), b()
showarray b()
PRINT "press a key";: SLEEP: CLS
PRINT " REDIM array A with _PRESERVE  "
REDIM _PRESERVE a(7, 6) AS INTEGER
showarray 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 _PRESERVE
PRINT " Redim Array A and NO _preserve "
REDIM a(8, 7) AS INTEGER
showarray a()
showarray b()
' no clear no erase because they take down dimensions of the array
PRINT " Restoring original array data into array A "
copyArray b(), a()
showarray a()
showarray b()
PRINT "Press a key ": SLEEP: CLS
PRINT " Now Redim A with NO _PRESERVE"
REDIM a(7, 6) AS INTEGER
showarray a()
showarray b()
PRINT " Restoring data using CopyArrayFOR "
CopyArrayFor b(), a()
showarray a()
showarray b()

END

SUB 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
NEXT
END SUB

SUB 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
PRINT
END SUB

SUB 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 SUB

SUB 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
NEXT
END 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.