How do you handle the poor performance of LC 7?

sanke at hrz.uni-kassel.de sanke at hrz.uni-kassel.de
Sun May 31 05:50:15 EDT 2015


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

---
Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft.
http://www.avast.com





More information about the use-livecode mailing list