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"
Free Web Hosting