Page 3 of 3
Performance comparison X# runtime vs Vulcan runtime
Posted: Mon Jul 02, 2018 11:38 am
by wriedmann
Hi Dick,
maybe I'm lazy, but I use AAdd() every time I don't know the exact length at the start of the loop.
Maybe one could ask first for the number of records and then preallocate the array, but as we have seen there is not soo much performance penalty.
Wolfgang
Performance comparison X# runtime vs Vulcan runtime
Posted: Mon Jul 02, 2018 12:11 pm
by FFF
Dick,
if you care to try Johan's code yourself, or read my observation, i'd simply stay lazy. The difference is neglectible, at least as long as you don't manipulate thousands of arrays with thousands of entries all at once...
Karl
Performance comparison X# runtime vs Vulcan runtime
Posted: Mon Jul 02, 2018 12:35 pm
by lumberjack
Hi Dick,
ic2 wrote:Hello Johan,
lumberjack wrote:
Was just mentioning it since using AAdd() in both instances or ArrayNew(), will show the performance penalty to the "lazy" programmers out there...
I'm catching up forum messages and I was intrigued by this remark. I have many places in my program where I use AAdd. E.g. we want a total of a series of general ledger accounts and for every record with a booking on a GL, we use AScan to see if we already added that GL in an array, if not, we AAdd to the GL array and the total value array.
Seems a good way to me, even AAdd is poor regarding performance.
What would the non lazy programmer do?
Dick
Ok, maybe as you catch up you will get to Wolfgang's test. Seems there is no performance penalty in X# anymore.
Performance comparison X# runtime vs Vulcan runtime
Posted: Mon Jul 02, 2018 5:05 pm
by Chris
Guys, also in X# it is always better to use ArrayCreate() instead of AAdd(), when you already know the length of the array, both in speed and in GC activity/memory usage terms. Run the following with the X# runtime test twice, once for AAdd() and once for ArrayCreate()) and you will see the differences.
Having said that, very very rarely one will need to create an array of 20000000 elements!
So for "normal" usages, the difference is really negligible, so I agree it's just better to use what everyone's more comfortable with. But in case you do create long arrays in tight loops, then ArrayCreate() is much better.
Code: Select all
FUNCTION DoTest() AS VOID
LOCAL nMemory AS INT64
LOCAL nElements AS INT
LOCAL dTime AS DateTime
LOCAL lUseAAdd AS LOGIC
LOCAL a AS ARRAY
nElements := 20000000
? "Press Space for AAdd() test, Return for ArrayCreate()"
lUseAAdd := Console.ReadKey():Key == ConsoleKey.Spacebar
? "Running test..."
nMemory := GC.GetTotalMemory(FALSE)
dTime := DateTime.Now
IF lUseAAdd
a := {}
FOR LOCAL n := 1 AS INT UPTO nElements
AAdd(a,n)
NEXT
ELSE
a := ArrayCreate(DWORD(nElements))
FOR LOCAL n := 1 AS INT UPTO nElements
a[n] := n
NEXT
END IF
? "Time elapsed:", (DateTime.Now - dTime):ToString()
? "Memory currently used (after possible collections):", (GC.GetTotalMemory(FALSE) - nMemory):ToString("###,###,###,### bytes")
? "The GC was invoked", GC.CollectionCount(0), "times"
WAIT
GC.KeepAlive(a)
RETURN
FUNCTION Start( ) AS VOID
DoTest()
RETURN