How do you handle the poor performance of LC 7?
Richard Gaskin
ambassador at fourthworld.com
Sun May 31 12:02:34 EDT 2015
Wilöhelm, as a fellow benchmarking fan I always look forward to your
ongoing graphics manipulation metrics with enthusiasm. Your tests are
well detailed, and you keep enviably complete notes on them.
I have a couple small thoughts on the tests themselves, and one about
the bigger picture of the suitability of this sort of work in LiveCode.
Small thing #1:
>- Scripts running in LC 4.6.1 are about 10 to 20% slower compared to
> running under the MC (Metacard) 4.6.1 IDE
There will always be difference in IDE overhead because the two IDEs are
written with very different goals in mind. MC attempts to provide the
bare minimum of GUI support, while LC strives for a more complete
experience. As much as I enjoyed MC, its Spartan nature was one of the
reasons I've amassed so many custom tools, often for things that are
already included with more feature completeness in the LC IDE.
Since the underlying engine is the same, there should be very little if
any difference at all in how it affects our final deliverable, the
standalone.
So while comparisons with MC may be useful for considering trimming
features from the LC IDE, in general they don't affect what we produce
with either IDE.
Small thing #2:
The comparisons across different engine versions which make up the bulk
of your post are indeed more helpful, but since these tests also include
the unsupported MC IDE for the older engine versions they'd be even more
helpful for identifying engine changes if they either used the same IDE
or a standalone build from the same IDE.
The bigger picture:
Many of us do ambitious things in LiveCode, and it's a wonder it lets us
do half of them at all. A surprisingly complete language given its
uncommon ease, we have deep control over binary structures just as we do
with parsing text; given the breadth of interests in our community the
engine gets tested across a wide range of task categories.
While it's nice to be able to work with a language this flexible, Kevin
himself is more restrictive in how he positions LiveCode's "sweet spot"
than many of us are.
For example, when v5.5 introduced the wonderful new field object, I was
quick to suggest we could now make a word processor with it - and Kevin
was equally quick to suggest we not:
LiveCode is for verticals, of which there are many to which
it is greatly suited. The new field features support those
and there is a much more flexibility in there now, not least
the textChanged message allowing a great deal of custom control.
However we would not recommend it for developing the next Word.
<http://lists.runrev.com/pipermail/use-livecode/2012-February/168802.html>
We're both right, in the sense that I do indeed make a word processor as
the core of one of my biggest projects right now, but it's a very
specialized, "vertical", word processor, one that won't in any way
compete with Microsoft Word. Mine is made only for the authoring of
specific content within one company, and with LiveCode we're spending a
fraction of what a much larger team in the same company spent making a
similar system.
Along those lines, it's possible to write image filters in LiveCode but
none of the professional image editing products attempt to do so in any
scripting language. While v7 is no doubt slower than earlier versions
in ways that might benefit other tasks as well, image filtering was
never LiveCode's sweet spot, nor with any general purpose scripting
language I've seen.
Historically the externals API was a good fit for that task, allowing us
to use LiveCode for the UI and handing off the heavy lifting of image
filtering to the language most commonly used for that, C.
In the future, v8 opens up an even better option: rather than rewriting
the world's image filters from scratch, it may be possible to use v8's
ability to talk directly to lower-level APIs to write a library that
would allow us to use the vast collection of existing third-party
Photoshop filters.
It may even be that such a subsystem already exists for Skia-based
graphics frameworks like LiveCode, or will someday soon, so all we'd
need to do is wire up the existing work to be exposed to our scripts.
None of this is to discourage your excellent benchmarking in this area.
On the contrary, optimizing operations on binary data merits attention
for a wide range of tasks; bitmap indices and Bloom filters come to mind
as logical compliments to LiveCode's grace with text handling, esp. now
that it uses the world standard of Unicode for richer language-savvy
parsing.
This is only to invite a 30,000 foot view, looking at the full range of
possible ways to solve problems as we craft our products.
There are hundreds of great languages, each bringing their own unique
value to the mix.
Sometimes the best solution for a given task isn't LiveCode.
But at least with LiveCode we often have the opportunity to leverage
work done in other languages more well suited, to harness them within a
complete application experience driven by LiveCode as the wrapper.
I've written enough data storage systems in pure LiveCode to appreciate
SQLite when that's what I truly need. :)
--
Richard Gaskin
LiveCode Community Manager
richard at livecode.org
Wilöhelm Sanke wrote:
> The somewhat "sluggish" behavior of all LC versions 7.x is apparent
> without testing a single script over several versions. Just use the LC
> IDE and copy and paste any object and you see how reluctantly the IDE
> performs these basic steps. In my case this is on a Windows machine with
> Windows 7 and 32 bit.
>
> More specially, I have tested this for imagedata processing, where I
> have set a personal focus these last years. I have several times filed
> bug reports accompanied by sample stacks. Recently I have repeated tests
> and added new ones comparing MC and LC versions from MC 4.6.1 to LC 8.0.
>
> The general (average) results on the basis of identical (or
> "corresponding" - see below) scripts are like this:
>
> - Scripts running in LC 4.6.1 are about 10 to 20% slower compared to
> running under the MC (Metacard) 4.6.1 IDE
> - Scripts in LC 6.7.5 are about 1.7 times slower than in MC 4.6.1
> - Scripts in versions LC 7.x run about 3 to 10 times slower, depending
> on the complexity of the script, compared to MC 4.6.1, which means for
> example that more time-consuming filters (without using DLLs) for image
> sizes 640x480 like convolution-matrix filters which might need 30
> seconds in MC 4.6.1 will run for 2 to 3 minutes under LC 7.0.4.
> With larger images you can easily reach ten and more minutes, which is
> inacceptable.
>
> These comparisons take into account that in versions 7.x you have to
> substitute char, chartonum, numtochar by byte, numtobyte, bytetonum -
> this is why I spoke of "corresponding" scripts above.
>
> You can use the byte-functions already in versions 4 to 6, but with some
> caveats:
>
> - The first is that "put bytetonum(numtobyte(-100))" (as an example)
> evaluates to "0" instead of 156 in "chartonum(numtochar(-100)). With
> filters possibly dealing with negative values like in my "duplicate
> colors"-algorithm you therefore get a totally black image after the 9th
> iteration instead of returning to the original image.
> - The second is that in certain contexts - as with matrix operations -
> you need to use a "hybrid" combination like "chartonum(numtobyte(x)" to
> avoid an error message.
>
> In versions 7.x pure "byte"-scripts are the norm, but "char"-scripts are
> tolerated up to (including) version 7.0.4.
> The use of any "char"-scripts in LC versions 7.0.5 immediately leads to
> crashes, resulting for example in opening the script editor without
> showing any part of the script and sometimes in removing all
> image-values stored in custom properties. After that I had to force-quit
> Livecode.
> When I tried to create a sample stack that could be opened both in MC
> 4.6.1 and LC 8.0 the menu items (entered in the properties inspector)
> of all case-statements in the menupick handlers became scrambled, but
> left the menupick scripts itself untouched. This effect was visible in
> each of the buttons on the card that used menupick handlers, meaning the
> distortion of the menu items appeared simultaneously.
>
> In LC 7.04 quite a number of scripts using bytes or chars respectively
> run with similar speeds sometimes with a slight overhead (slower) for
> scripts using chars, but, as already mentioned, 4 to 10 times slower
> compared to MC 4.6.1
>
> Here is an elementary example script for an internal "mirror from right"
> (the right side of the image is mirrored on the left side):
>
> "on mouseUp
> set the cursor to watch
> put the milliseconds into Start
> put the imageData of image x into iData
> put the height of img x into theight
> put the width of img x into twidth
> set the endvalue of scrollbar 1 to theight
> put trunc(theight/30) into scrollstep
> put 4* twidth into re
> put twidth/2 into twhalf
> repeat with i = 0 to theight - 1
> if i mod scrollstep = 0 then set the thumbpos of scrollbar 1 to i
> put i*re into ti
> put -1 into DiffJ
> repeat with j = twhalf to twidth - 1
> add 2 to DiffJ
> put char (ti + (j*4+2)) of idata into char (ti + ((j-DiffJ)*4
> +2)) of idata
> put char (ti + (j*4+3)) of idata into char (ti + ((j-DiffJ)*4
> +3)) of idata
> put char (ti + (j*4+4)) of idata into char (ti + ((j-DiffJ)*4
> +4)) of idata
> end repeat
> end repeat
> set the imageData of image x to iData
> put the milliseconds - Start into fld "Test"
> set the thumbpos of scrollbar 1 to theight
> end mouseUp"
>
> Speed tests for this script under MC 4.6.1 with different image sizes in
> milliseconds - using "byte" instead of "char" in the sample script above
> for the second row:
>
> 320x240 480x360 512x384 640x480
> chars 104 179 203 303
> bytes 104 186 203 296
>
> Corresponding values for LC 7.0.4:
>
> 320x240 480x360 512x384 640x480
> chars 1449 1692 1842 2087
> bytes 1407 1641 1793 2003
>
> I noticed however that *some* scripts running relatively fast under MC
> 4.6.1 could take up to 2000 (two thousand) times longer -and even more
> depending on image size - with LC 7.0.4. It was difficult to find out
> the common cause for these ultra-slow scripts. At least one of the
> causes for the ultra-slow speed is that these scripts used two sets of
> imagedata in variables "idata" and "idata2", because - when relocating
> pixels in an image - sometimes the area of the source pixels overlaps
> with that of the target pixels. This can for example happen when you
> wish to combine two images (superimposing or partly overlapping) or when
> you turn a rect inside an image for 90 degrees.
>
> In the sample script above no such overlapping of source and target
> pixels occurs, but we can simulate this effect nevertheless by creating
> two sets of imagedata adding the line
>
> "put idata into idata2" to the script
>
> and then changing the core part of the sample script to
>
> "put char (ti + (j*4+2)) of idata2 into char (ti + ((j-DiffJ)*4 +2)) of
> idata
> put char (ti + (j*4+3)) of idata2 into char (ti + ((j-DiffJ)*4 +3)) of idata
> put char (ti + (j*4+4)) of idata2 into char (ti + ((j-DiffJ)*4 +4)) of
> idata".
>
> Results of these changes in LC 7.0.4:
>
> 320x240 480x360 512x384 640x480
> chars 25168 163495 216116 576434
> bytes 1407 1641 1793 2003
>
> The results for the byte-version "put byte (ti + (j*4+2)) of idata2 into
> byte (ti + ((j-DiffJ)*4 +2)) of idata" etc. remained the same as for the
> script using only one set of imagedata. Under MC 4.6.1 there is likewise
> no difference between using one or two sets of imagedata both for char
> and byte-scripts.
>
> Speed of the two-set imagedata script in LC 7.0.4 for an image size of
> 640x480 is with 576434 milliseconds 1902 times slower than with the same
> script under MC 4,6,1, which needs only 303 milliseconds.
>
> I know that there are alternatives for instance using arrays, and I
> haved tested them, but they are not necessarily faster in all cases.
>
>
> Best regards,
>
> Wilöhelm Sanke
More information about the use-livecode
mailing list