Page 1 of 2
How can I speed up this code?
Posted: Fri Mar 29, 2013 6:07 pm
by user#606
I have removed all the code I can run elsewhere and am left with this.
It takes about 9 seconds to run through a table of data about 150 lines. This is unaceptable, because it is part of a "behind the scenes" refresh and the user will experience an unexpected freeze.
If a larger data sample is in the table, obviously, the problem gets much worse.
Code: Select all
on mouseUp
local NumLines, LineCount,Temp,Temp1
set itemdelimiter to tab
set the twelveHourTime to false
set the useSystemDate to true
put number of lines of field "Table 1" into NumLines
put the time into Temp1
convert Temp1 to seconds
put 0 into LineCount
repeat for NumLines
put 1 + LineCount into LineCount
if item 13 of line LineCount of Field "Table 1" > 0 then
if item 13 of line LineCount of Field "Table 1" > Temp1 then
set the backgroundColor of line LineCount of field "Table 1" to "yellow"
else
set the backgroundColor of line LineCount of field "Table 1" to "red"
end if
else
put empty into item 13 of line LineCount of Field "Table 1"
set the backgroundColor of line LineCount of field "Table 1" to empty
end if
-- sort lines of Field "Table 1" descending numeric by item 13 of each -- this makes no visible difference
end repeat
end mouseUp
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 6:16 pm
by FourthWorld
These two tips should give you at least an order of magnitude performance boost:
1. Move data from fields to variables when you need to do a lot of work on it:
http://lists.runrev.com/pipermail/use-l ... 11478.html
2. Use the "repeat for each" form when practical:
http://lists.runrev.com/pipermail/use-l ... 19032.html
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 6:26 pm
by dunbarx
Hi.
You use a lot of field references, where variable references would be much faster. That said, isn't it true that the "htmlText" tags color as well as font attributes?
Put all your field data into a variable first, and set the htmlText of the items of that variable just as you did with the contents of the field, and then load the field all at once.
I hope I understand that the htmlText of a variable does what I think it does with regards to color. Or that you can set the htmlText within a variable at all.
EDIT:
Oops, maybe you cannot set that in a variable, but rather only in an object, like a field.
Craig Newman
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 7:03 pm
by dunbarx
Richard and I both zeroed in on the fact that you should not refer to fields thousands of times in a handler, but rather once or twice. So with what I failed to provide a solution for, unless there is a "variable" method of setting attributes such as color, you will have to kluge this.
You say:
if item 13 of line LineCount of Field "Table 1" > 0 then
if item 13 of line LineCount of Field "Table 1" > Temp1 then
set the backgroundColor of line LineCount of field "Table 1" to "yellow"
If the field text was in a variable, called say, "myData", then you would write something like:
if item 13 of line LineCount of myData > 0 then
if item 13 of line LineCount of myData > Temp1 then
put "<b><i>line LineCount of myData</i></b>" into line lineCount of myData
Now I just copied a line from the htmlText entry in the dictionary, and the tags deal with italics and boldness. But background color tags are all available.
But do you see? Instead of setting the backGroundColor of lines of a field, which is slow, you build the htmlText tags of the relevant portions of your data in a variable, and when you reload the whole thing, the attributes can be set:
set the htmlText of fld "table 1" to myData.
Craig Newman
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 8:49 pm
by Simon
I'm not sure of this but isn't switch/case faster than if/then?
switch
case myData > 0
--do something
break
case myData > temp1
-- something else
break
end switch
Don't know if thats true... but if anyone knows?
Simon
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 9:33 pm
by dunbarx
Simon.
Not sure, but I bet it makes little practical difference. A simple test would tell, though.
The issue here is that many,many times a field is read or written to.
No no.
Craig
Re: How can I speed up this code?
Posted: Fri Mar 29, 2013 11:40 pm
by Simon
Ok I did a test and I'm amazed that if/else if is slightly faster than switch/case.
Multiple if/then is slightly slower then switch/case.
I had thought break would make the switch faster.
But I agree the real problem is working in the field not with a variable.
Simon
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 12:45 am
by sturgis
To work with the text in an array you can use "styledtext" (check dictionary) and build up an array describing the textstyles affecting the text in the variable, then apply it to the field.
Might be a pain to get the ins and outs at first but should work ok for this.
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 1:19 am
by dunbarx
Sturgis.
The dictionary talks about the "styledText" in the same way that it does to the "htmlText" That is, it addresses field data, not variable data.
If I misread this, however, in that you can create an array variable and work on that, then it certainly makes the kluge I suggested simpler. You can color an element in an array variable, and not have to construct the htmlText tags as chunks of a string.
Craig
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 1:34 am
by sturgis
Yeah thats what I meant. Construct the array against the variable then when is applied to the field it should transform the text to the desired look. The format of the array doesn't look too difficult to work with either. Paragraphs, and text runs within paragraphs. More straightforward than I expected it to be if anything.
So basically, shove the field text into a variable. repeat for each with a hand "counter" to keep track of line (paragraph) to create the array then apply it. Should work pretty well. I think.
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 11:09 am
by user#606
Firstly, thank you all for your help and advice.
I have reworked the code based on the points raised.
Unchanged, the code runs in about 9 seconds.
With the IF statements in a variable, not a table address, this brings it down to about 7 seconds.
However, because the table address changes per line, the table address value has to be put into the variable every iteration.
The first IF hapens every line, so there is no gain here, but the second IF hapens rarely.
In conclusion, the variable is vastly better than addressing the tabl;e address. This confirms your expert advice.
If the background colour statements are removed, the timing drops to about 5 seconds.
In this case, the use of html has not been tried, because unknown to you advisors, the line is transfered to another field for viewing and back to the table. This makes html messy, because the viewing field may have text from a web page copied to it in all sorts of font, colour, size etc and on return to the field, this gets stripped away. I want this. The line colour remains intact, by comparison, I want that also.
However, it does prove that such line background colouring, happening rarely, makes a tremendous difference by slowing the program.
Sorry this has been so long winded, but I and perhaps others, will benifit from the experiment.
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 11:21 am
by FourthWorld
user#606 wrote:With the IF statements in a variable, not a table address, this brings it down to about 7 seconds.
Please post a sample stack with complete code and sample date set. I wasn't kidding when I suggested you should see a performance improvement of about an order of magnitude.
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 1:48 pm
by user#606
Hi Richard,
I have sent a message direct to you, because the data in the program is of a private/sensitive/confidential nature and it is just not practical to generate a lot of it as ipsum loreum etc....
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 3:50 pm
by FourthWorld
Thank you for the note, but to be honest I'm not in a position to be able to review the entire project. What I can do is rewrite the one handler you've revised since the first post, provided you can also supply some data to test it with. It need not be the actual data your project uses; anything structured similarly and of roughly equivalent size will do.
If you could post an EXAMPLE stack containing those items here, I'll be able to make enough time to rewrite that one handler.
Then again, it may not be necessary - earlier you wrote:
"With the IF statements in a variable, not a table address, this brings it down to about 7 seconds."
The IF statements aren't the problem. The bigger issue is the REPEAT - if you first put the field contents into a variable before the REPEAT, the perform all of the REPEAT steps on that variable, by the time you put the data back into the field you will have saved significant time.
Did you read the two links in my first post here?
The second item there is also important, about which form of REPEAT is used.
Together, those two changes (moving all of the work out of the field into a variable, and using "repeat for each...") will likely bring an overall improvement of roughly an order of magnitude, for the reasons described in the posts I linked to.
I'm happy to rewrite the handler as shown here if needed - shouldn't take but a couple minutes. But to measure the effectiveness of the changes it would be helpful to have some representative data to work with.
Re: How can I speed up this code?
Posted: Sat Mar 30, 2013 4:11 pm
by user#606
Dear Richard,
I only suggested sending the whole folder, so everything was in place, working and more importantly, in context.
I realsise you would not be available to review the whole project.
The code that when fast enough is in here
Code: Select all
on mouseUp
local NumLines, LineCount,Temp,Temp1, Item13,
set itemdelimiter to tab
put number of lines of field "Table 1" into NumLines
put 0 into LineCount
repeat for NumLines
put 1 + LineCount into LineCount
put item 13 of line LineCount of Field "Table 1" into Item13
if Item13 > 0 then
if Item13 > Temp1 then
set the backgroundColor of line LineCount of field "Table 1" to "yellow"
else
set the backgroundColor of line LineCount of field "Table 1" to "red"
end if
else
put empty into item 13 of line LineCount of Field "Table 1"
set the backgroundColor of line LineCount of field "Table 1" to empty
end if
sort lines of Field "Table 1" descending numeric by item 13 of each
end repeat
end mouseUp
it will be transfered to the background process if it is practical.
I cannot provide any data, all I can do is replace my code with yours and report here, the improvement.
I greatly appreciate your help and I am sure others will when they see your magic!