Which is faster...
Paul Dupuis
paul at researchware.com
Fri Dec 15 10:53:42 EST 2023
And that is THE DEFINITIVE answer!
Wow! Thank you.
On 12/15/2023 10:00 AM, Mark Waddingham via use-livecode wrote:
> On 2023-12-14 21:22, Paul Dupuis via use-livecode wrote:
>> Which is faster or more efficient (from an engine performance
>> perspective)?
>>
>> To retrieve an array from a property?
>> As in:
>> command someHandler -- in an objects script
>> get the cMyArray from me -- cMyArray is some multi-dimensional array
>> ...
>> end someHandler
>>
>> OR
>>
>> To retrieve an array from a script local variable?
>> As in:
>> local sMyArray -- script local variable in some objects script
>>
>> command someHandler -- in an objects script
>> get sMyArray
>> ...
>> end someHandler
>>
>> Anyone know?
>
> Fetching a value directly from a variable will always be faster than
> any other method - as it essentially reduces to fetching or storing a
> value from a (integer indexed) table.
>
> In contrast, fetching a custom property will require a message send
> unless lock messages is set, and then an array lookup (to actually get
> the property's value).
>
> Custom property sets are stored using the same data structure
> internally as livecode arrays so getting `the cMyArray of me`
> eventually reduces to the same as
> objectsCurrentPropertySet["cMyArray"] - the latter lookup is more work
> than just fetching a value from an internal table.
>
> UPSHOT:
>
> Fetching a value directly from a variable is a constant time operation.
>
> If lock messages is false, then the time it takes to fetch a custom
> property value will be somewhat proportional to the length of the
> message path from the point of view of the object you are accessing -
> i.e. how many frontscripts, backscripts, stacks in use, and parent
> objects/behaviors the object has.
>
> If lock messages is true, then the time it takes to fetch a custom
> property value will be pretty much the same as doing an LC array key
> lookup.
>
> Now whether or not this actually matters in any one case will largely
> depend on how often such access is being done - if its a few times in
> the context of UI-related code then it probably won't be appreciable;
> if, however, you are fetching a custom property 100000's of times in a
> tight loop and the rest of the loop is only doing small amounts of
> work, you'll definitely notice a difference.
>
> SIMPLE BENCHMARK:
>
> ```
>
> on mouseUp
> local sMyArray
>
> on mouseUp
> set the cMyArray of me to [ 1, 2, 3 ]
> put empty
>
> local tTime
> put the milliseconds into tTime
> repeat 1000000 times
> get the cMyArray of me
> end repeat
> put "CUSTOM PROP:" && the milliseconds - tTime & return after msg
>
> put the milliseconds into tTime
> lock messages
> repeat 1000000 times
> get the cMyArray of me
> end repeat
> unlock messages
> put "CUSTOM PROP (LOCKED OUTSIDE):" && the milliseconds - tTime &
> return after msg
>
> put the milliseconds into tTime
> repeat 1000000 times
> lock messages
> get the cMyArray of me
> unlock messages
> end repeat
> put "CUSTOM PROP (LOCKED INSIDE):" && the milliseconds - tTime &
> return after msg
>
> local tMyProps
> put [ 1, 2, 3 ] into tMyProps["cMyArray"]
> put the milliseconds into tTime
> repeat 1000000 times
> get sMyArray["cMyArray"]
> end repeat
> put "ARRAY ELEMENT:" && the milliseconds - tTime & return after msg
>
> put the milliseconds into tTime
> lock messages
> repeat 1000000 times
> get sMyArray
> end repeat
> unlock messages
> put "SCRIPT LOCAL:" && the milliseconds - tTime & return after msg
> end mouseUp
> end mouseUp
> ```
>
> RESULTS (1 million iterations):
>
> CUSTOM PROP: 2006
> CUSTOM PROP (LOCKED OUTSIDE): 116
> CUSTOM PROP (LOCKED INSIDE): 125
> ARRAY ELEMENT: 80
> SCRIPT LOCAL: 38
>
> ANALYSIS:
>
> The above results are run in the IDE which is important to mention
> because the message path in the IDE is typically longer than that in
> standalones (as the all extension libraries are loaded, and the IDE
> inserts its own front/back/stacks into the message path).
>
> Accessing custom properties with messages locked is nearly 10x faster
> than without (again that multiplier will be vary with the length of
> the message path).
>
> Using lock/unlock messages for every custom property access has a
> (quite negligible) 10% overhead - and the message path overhead (in
> the IDE) is about 40% of the total (the array element fetch will be
> the rest).
>
> Accessing a script local is
> - about 50x faster than accessing a custom property when messages
> are sent
> - about 3x faster than accessing a custom property when messages are
> not sent
> - about 2x faster than accessing an array element
>
> Just to reiterate - these figures are for 1,000,000 accesses done in a
> tight loop (in the IDE). If you do it for (say) 1000 iterations then
> the differences are within the margin of error of measuring a
> millisecond.
>
> Overall, my suggestion would be probably to do a combination of both -
> if you are only reading from a custom property in a given loop, but
> are doing so multiple times for the same property (and the loop
> actually has a very high number of iterations!) then fetch into a
> local variable before the loop and then use that value (the same, to
> be fair, is true of calling functions which return fixed values and
> accessing array elements - especially ones on paths longer than one).
>
> Hope this helps,
>
> Mark.
>
More information about the use-livecode
mailing list