getProp syntax query
Richard Gaskin
ambassador at fourthworld.com
Tue Apr 3 11:17:37 EDT 2012
Graham Samuel wrote:
> On Mon, 2 Apr 2012 Mark Schonewille wrote:
...
>> You can use only one index, i.e. the setProp/getProp handlers
>> are one-dimensional.
...
> Mark, thanks for that. There is absolutely nothing of this in the
> LC Dictionary AFAICS, although after a search I realised that
> there is a very hard to read (IMHO) description on section 7.10
> of the User Guide. I think at the very least a note should be
> added to the Dictionary entry, so I have submitted one, but I
> would be very happy if someone such as yourself corrects it.
Or you could do that yourself, with the Comments feature. Probably a
useful note to add until that Dict entry gets enhanced.
In fact, it would be great to submit an RQCC request for this Dict
issue, so it will be on RunRev's radar.
At the heart of this is a core difference between how arrays and custom
props are handled. They seem similar but have diverged in recent years:
In the olden days, both LiveCode's associative arrays and the custom
properties it allows in objects were parallel: they were one
dimensional, and you could move data between them easily:
put the customProperties of tObj into tMyArray
set the customProperties of tObj to tMyArray
When arrays became multi-dimensional, that made it difficult to use the
same syntax to accomplish similar goals, so they created a workaround to
support that which also gave rise to two new functions, arrayEncode and
arrayDecode.
ArrayEncode translates an array from the memory-specific hash table that
drives it into a flat form that can be saved to disk. ArrayDecode
translates that flattened form back into an array in memory.
But since memory-mapped hash tables can't be used from disk, the format
of data returned from arrayEncode is not easily traversed, requiring
considerable clock cycles to translate back into an array when run
though arrayDecode.
In essence, what those functions do is somewhat similar to what you'd
have to do if you wanted to flatten array data in a script, walking
through each element and writing it out into a linear format that
retains key-value association, nesting, etc.
When you save an array to a custom prop, from what I'm seeing in terms
of performance it seems that the array data is passed through something
very similar to the internal routine used for arrayEncode, allowing that
binary data to be storable, but unfortunately not in a form that's
easily traversed.
And since those can't be traversed using the same rapid methods that
memory-based arrays use, we have no ability to use multi-dimensional
array syntax to address them as properties like we do as arrays.
For the long term I've submitted a request to see if we can come up with
a b-tree storage method which might allow us to use the same syntax for
both arrays and nested props:
Make arrays and customProperties behave the same
<http://quality.runrev.com/show_bug.cgi?id=6912>
In the meantime, to access array data stored in a custom prop requires
two steps, first to extract the array and then to access its nested
elements:
put the MyPropArray of tObj into tSomeArray
put tSomeArray[1][2] into tSomeValue
Note that performance of nested arrays as props is roughly on par with
running data that had been saved with arrayEncode through the
arrayEncode function, not nearly as fast as using a true array in a
variable. So for performance-critical uses it may be helpful to extract
the array early on and use it from a global, storing it back only when
needed.
This is a good opportunity to share a bit of geeky fun news with you folks:
Kevin Miller and Ben Beaumont have generously asked Mark Waddingham to
take a moment away from his very busy schedule to provide a description
of the format of the data we get from arrayEncode.
I had requested this because I have a few cases where I need to be able
to extract a specific data element from an array stored on disk, without
the overhead of reading the entire file and running it through
arrayDecode. This is for a CGI where every millisecond counts, and
some of the arrays I'm working with have hundreds of thousands of nested
keys.
To justify the time required for Mark to do this, we made a deal: Mark
would provide a sparse description only sufficient to get me started so
he could get back to more critical tasks, provided I take that info and
flesh it out into an article for LiveCode Journal which explains the
format in detail and provides a working example of how to use it.
Mark came through on his end of the bargain wonderfully, providing a
sample function that worked on the first level of array keys, which was
enough for me to expand it to be able extract the data from any key
regardless of depth.
The article explaining it all is in progress now and close to done. I
expect to be able to post it to LiveCode Journal by Saturday.
Here's a tantalizing tidbit to whet your appetite:
The sample stack I wrote for this creates a three-dimensional array with
100 items in each dimension, resulting in an arrayEncoded file with 1
million elements that's about 20 MBs on disk.
The function I made from Mark's example code can extract the data from
any element in that file in about 3 to 5 milliseconds.
Hint: the function makes heavy use of the binaryDecode function and the
seek command, both of which are explained in depth in the article and
which you may find very valuable for a wide variety of uses. The seek
command is a god for rapidly traversing large files easily.
I look forward to sharing this with you ASAP -
--
Richard Gaskin
Fourth World
LiveCode training and consulting: http://www.fourthworld.com
Webzine for LiveCode developers: http://www.LiveCodeJournal.com
LiveCode Journal blog: http://LiveCodejournal.com/blog.irv
More information about the use-livecode
mailing list