Author Topic: Static vs dynamic arrays  (Read 5236 times)

0 Members and 1 Guest are viewing this topic.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Static vs dynamic arrays
« on: October 30, 2020, 03:19:05 am »
How do you folk decide when an array should be dynamic or static? Seems it
was a much bigger problem with QB4.5 because you'd run out of memory with
too many large static arrays, a matter of where they were stored.  With
QB64 and modern computers it seems less of an issue.  Or is it?

Are the only pros/cons that dynamic can be redimensioned and static ERASEd?

I've been using _MEM to quickly move/copy dynamic arrays, so far with no problem. 
Does _MEM care what type they are?

I'd also like to know if it makes any difference to execution speed, but I suppose
I could test that on my own.

« Last Edit: October 30, 2020, 03:29:18 am by Richard Frost »
It works better if you plug it in.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Static vs dynamic arrays
« Reply #1 on: October 30, 2020, 04:03:35 am »
Good 'ol QuickBASIC restrictions. I had to use $DYNAMIC at the start of my code, just to get enough free memory for it to keep running. Also, there was something else. I think you could use CLEAR , , 2000 to allocate more memory from the stack. I have never had this issue with QB64.

As for speed, I've never had reason to test it, as non-gaming apps just don't have to move that fast, eve in not so quick, QuickBASIC.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Static vs dynamic arrays
« Reply #2 on: October 30, 2020, 04:25:57 am »
There is no reason to ever use static arrays.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Static vs dynamic arrays
« Reply #3 on: October 30, 2020, 09:54:13 am »
There is no reason to ever use static arrays.

Well, one reason only:  It saves typing two whole bytes.  (DIM vs REDIM)   :P

Honestly, I don't see why dynamic isn't the default behavior for arrays, rather than static creation.  If you never need to REDIM an array, you simply wouldn't issue a REDIM command a second time to change the size of it. 

As for _MEM, it doesn't make a bit of difference between DIM and REDIM, as far as its concerned, with one caveat:

If you REDIM an array that has a memblock pointed to it, you'll free that memblock automatically.  Trying to reference it at that point will crash your program, as illustrated with the simple demo below:

Code: QB64: [Select]
  1. m = _MEM(x())
  2. _MEMPUT m, m.OFFSET + 4, 123 AS INTEGER
  3. FOR i = 0 TO 10
  4.     PRINT i, x(i) 'when i is 2, our value for x(2) should be 123, as that's the value of the 4th and 5th byte in our array.  (An integer is 2 bytes each, and we start at byte 0, and I _MEMPUT at byte 4).
  5.  
  6.  
  7.  
  8.  
  9. _MEMPUT m, m.OFFSET, 321 AS INTEGER 'and here we get an error which will terminate our program:  MEMORY HAS BEEN FREED.  You can't access memory at the old address, when you dynamically moved it around to someplace new.
  10.  
  11.  
  12. m = _MEM(x()) 'instead, remark out the line above, and re-reference the memory with a new statement, like the one on this line.
  13. _MEMPUT m, m.OFFSET, 321 AS INTEGER 'and then you can get or put the data as you want
  14.  
  15.  
  16. FOR i = 0 TO 8
  17.     PRINT i, x(i)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Static vs dynamic arrays
« Reply #4 on: October 30, 2020, 12:21:46 pm »
I always thought STATIC arrays were faster (because they had permanent and perhaps continuous block set aside whereas dynamic gets fragmented like the hard disk), so if you never needed to change the size go with that.

If there is no difference in speed and no potential memory access then it sounds like Dynamic is better.
« Last Edit: October 30, 2020, 12:28:20 pm by bplus »

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Static vs dynamic arrays
« Reply #5 on: October 30, 2020, 08:34:28 pm »
To elaborate a little more:

In QuickBasic, data was either near or far (a consequence of the x86's real-mode segment memory model). Data that was near could be accessed more efficiently because you didn't have to do segment calculations, you just used a 16-bit offset (this is the "DGROUP" you may have heard of). Far data was in a different segment and required a little more work to get at because you had a segment:offset point to deal with. But you only have one DGROUP and it's 64KB (one segment) in size. Most program variables, as well as QB's internal data structures, live there so memory can get tight.

A STATIC array is near, so has its values stored in DGROUP. This makes it somewhat more efficient but uses precious DGROUP space. A DYNAMIC array is far, stored in a different segment so as to not fill DGROUP. In all cases a given array's elements are stored contiguously.

In QB64 there's no segments and everything just gets allocated on the heap, so there's no real difference any more.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Static vs dynamic arrays
« Reply #6 on: October 30, 2020, 09:40:48 pm »
Thanks a heap for the explanation.

Pete :D

The older I get, the more far memory I use.
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Static vs dynamic arrays
« Reply #7 on: October 30, 2020, 10:46:16 pm »
So you $DYNAMIC fans probably never use ERASE, since REDIM can't be used in SUBs.  That means
a loop to fill a numeric array  with zeros - or some trickery with _MEMCOPY.  The arrays I want
to zero aren't in a time critical section of my code, so the main concern for me is to keep the
line count down and have code that's easy to understand.  It's old-fashioned to care about line
count, eh? 

Don't ANY of you guys intentionally use static arrays, sometimes?  I gotta put "dinosaur" on my resume?

Thanks for the explanation re speed, that it makes no difference, and why.  Saves me some dull testing,
because someday this choice will have a bearing on a section of code where speed matters.
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Static vs dynamic arrays
« Reply #8 on: October 31, 2020, 12:16:52 am »
Quote
since REDIM can't be used in SUBs

Wait what?

I don't use $DYNAMIC, I just "DIM" a dynamic array as REDIM myDynArr(new dimensions or old) and that 0's out and that can be used in SUB, who uses $DYNAMIC anyway? why? Isn't it just one of those commands we keep around for old code compatibility?

BTW I don't remember ERASE (for STATIC arrays) from QB4.5 at all, was it used then? Maybe I never needed to zero out an array???

And yes, I use to use Static arrays all the time, but now? thanks to this thread, maybe not.
« Last Edit: October 31, 2020, 12:23:49 am by bplus »

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Static vs dynamic arrays
« Reply #9 on: October 31, 2020, 01:01:09 am »
Yes, QB4.5 had ERASE, and like QB64 it was only for static arrays.   The issue is re-initializing an
array in a SUB, B+, not creating them.  Surely you have to do that, sometimes.

I vunder vot odder commands noboddy usingk.  GET/PUT graphics?

I'll follow you experts and also USUALLY use dynamic arrays, exception being when I really want
to use ERASE.  Because pencil erasers create employment for some.   And I sure hope I'm right in
thinking that arrays dimensioned with variables are dynamic and ones with explicit values are
static, in the absense of the metacommand, so I don't have to do all one or the other. 
« Last Edit: October 31, 2020, 01:20:25 am by Richard Frost »
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Static vs dynamic arrays
« Reply #10 on: October 31, 2020, 01:17:17 am »
On the issue of clearing a dynamic AND giving it new dimensions here a Lower bound:
Code: QB64: [Select]
  1. REDIM SHARED myDynArr(1 TO 20) AS LONG
  2.  
  3. FOR i = LBOUND(myDynArr) TO UBOUND(myDynArr)
  4.     myDynArr(i) = i
  5.     PRINT i, myDynArr(i)
  6. PRINT "Press any ..."
  7.     foo myDynArr()
  8.     PRINT: PRINT
  9.     FOR i = LBOUND(myDynArr) TO UBOUND(myDynArr)
  10.         PRINT i; ":"; myDynArr(i),
  11.     NEXT
  12.     PRINT "Press any ..."
  13.     SLEEP
  14.  
  15. SUB foo (aDynArr() AS LONG)
  16.     lb = RND * 100 - 50: ub = 51
  17.     REDIM aDynArr(lb TO ub) AS LONG
  18.  

Just REDIM the array all will be erased.


Quote
And I sure hope I'm right in
thinking that arrays dimensioned with variables are dynamic and ones with explicit values are
static, in the absense of the metacommand, so I don't have to do all one or the other.

Nine! Nein
REDIM starts a Dynamic array or re initializes BOTH.

« Last Edit: October 31, 2020, 01:33:08 am by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Static vs dynamic arrays
« Reply #11 on: October 31, 2020, 01:38:03 am »
Even REDIM dynamic array with same dimensions and all will be erased.

Code: QB64: [Select]
  1. REDIM SHARED myDynArr(1 TO 20) AS LONG
  2.  
  3. FOR i = LBOUND(myDynArr) TO UBOUND(myDynArr)
  4.     myDynArr(i) = i
  5.     PRINT i, myDynArr(i)
  6. PRINT "Press any ..."
  7.     foo myDynArr()
  8.     PRINT: PRINT
  9.     FOR i = LBOUND(myDynArr) TO UBOUND(myDynArr)
  10.         PRINT i; ":"; myDynArr(i),
  11.         ' now muddle it
  12.         myDynArr(i) = RND * 100
  13.     NEXT
  14.     PRINT "Press any ..."
  15.     SLEEP
  16.  
  17. SUB foo (aDynArr() AS LONG)
  18.     lb = LBOUND(aDynArr): ub = UBOUND(aDynArr)
  19.     REDIM aDynArr(lb TO ub) AS LONG
  20.  
« Last Edit: October 31, 2020, 01:40:57 am by bplus »

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Static vs dynamic arrays
« Reply #12 on: October 31, 2020, 01:40:15 am »
in a SUB

in a SUB

in a SUB

Ye kanna REDIM in a SUB

"We all live in a yellow submarine."  - Ringo
It works better if you plug it in.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Static vs dynamic arrays
« Reply #13 on: October 31, 2020, 01:42:19 am »
in a SUB

in a SUB

in a SUB

Ye kanna REDIM in a SUB

"We all live in a yellow submarine."  - Ringo


Are you saying you want to see REDIM used in a SUB because I've given 2 examples already?

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Static vs dynamic arrays
« Reply #14 on: October 31, 2020, 01:45:08 am »
Eep.  Er.  Thought I got an error message saying I could not do that.
Now I'm really confused. 

Got it.  Sorry I wasn't clear.  It's a SHARED array.  That's why it isn't
legit to REDIM it in a SUB.  Unless I leave off the SHARED.  Then what
happens?  I find out...

Works fine, which suprised me.  Other SUBs can still access it.  Duh.
Sorry.  I give this entire matter a big rethink.  So.....ERASE is really
stupid, REDIM is the better way?  ERASE is just for QB4.5 compatibility?
« Last Edit: October 31, 2020, 02:06:47 am by Richard Frost »
It works better if you plug it in.