Array property trick
<< Back
Before reading this article, please take a few minutes to read through this awesome
blog post
from Sonny Falk.
Now, back to business. If you have a property that stores a large array of something, you might notice that modifying the property will take a long time.
When the program executes to line 16, you might notice that the program takes a second or two in order to append an item to the array. Also if you put a break point
on both line 16 and line 17, the memory consumption of the program will double during that time. Why?
The answer is in the blog post above. At the end of the post, Sonny basically said "Don't use accessor methods". However, take the scenario where
you get a bunch of data from a web service (or SQL call, or read from a excel file), and you are able to store that info at once without using any
accessor methods. Later on, you have to add on to those data through UI (you provide an entry view for user to add one record at a time).
Use VDFBase
Object oTest is a cObject
Property String[] psStrings
Procedure Init // Add a bunch of strings to the psStrings property
String[] s
Integer i
Move (ResizeArray(s,2000000)) to s
For i From 0 to 1999999
Move (Repeat("a",400)) to s[i]
Loop
Set psStrings to s
End_Procedure
Procedure AddString String sNewString
String[] s
Get psStrings to s
Move sNewString to s[SizeOfArray(s)]
Set psStrings to s
End_Procedure
End_Object
Send Init of oTest
Send AddString of oTest "Hello"
However is there any way to avoid the copying? After all, I don't want to take two seconds just to append an item to an array.
Well, my friend, here is a little trick. Notice line 16 again. This time I would blank out the property, thus there is only one copy of the huge array.
There is NO making a complete copy of a huge array, there is NO memory spike, everyone is happy.
Use VDFBase
Object oTest is a cObject
Property String[] psStrings
Procedure Init // Add a bunch of strings to the psStrings property
String[] s
Integer i
Move (ResizeArray(s,2000000)) to s
For i From 0 to 1999999
Move (Repeat("a",400)) to s[i]
Loop
Set psStrings to s
End_Procedure
Procedure AddString String sNewString
String[] s sBlank
Get psStrings to s
Set psStrings to sBlank
Move sNewString to s[SizeOfArray(s)]
Set psStrings to s
End_Procedure
End_Object
Send Init of oTest
Send AddString of oTest "Hello"