| Notices | Welcome to RetouchPRO . You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload images and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. | | Photoshop Scripting Learning and sharing for all platforms | 
02-02-2005, 08:16 AM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,548
| | | Speeding up script execution I have been doing some scripts that have nested loops to process an image.
Problem is, my present machine is slow and I need a lot of iterations. Does anyone have general guides on how to speed up script execution?
Like:
- take out all comments;
- define eveything at the start (or at the end);
- use / don't use user-defined functions;
- put the loops at the beginning.
I plan to test some alternatives, but maybe someone can give me a jump start.
Rô | 
02-02-2005, 09:35 AM
|  | Senior Member | | Join Date: Jul 2004 Location: Czech Rep.
Posts: 257
| | i don't know anything about PS scripts, all said here referes to C/C++, but should be similar...
- take out all comments;
scripts are parsed (to be exact, at least in 2 passes); comments are taken out automatically in the first pass, and don't effect efficiency
- define eveything at the start (or at the end);
same as prev., necessary memory (except of the dynamically allocated one) is allocated before execution
- use / don't use user-defined functions;
if correctly/properly written, user-defined functions (in java/javascript) are (almost) as quick as standard ones; but, if functions you wanna use are really short (2 to 10 lines), consider possibility of putting the code directly in, instead of calling it as a function ("inline" directive in C does this for you)
- put the loops at the beginning.
no real effect; more important thing is to avoid loops nesting if possible, and expanding short loops - eg. if you have something like
for (i=-1; i <= 1; i++) something(i);
use rather
something(-1);
something(0);
something(1);
anyways, these things are mostly pointless unless you're sure you have the BEST algorithm available! code optimization can give you up to 50% speed up on the high level of code (ie. changing the javascript code; assembler can give higher values, but that's not important here), while proper design/choice of algorithm can give you speed up in 100's or 1000's of percent...
if there are 3+ nested loops of big length (eg. dimension of picture), something's wrong w/ the algorithm... try using coherence, investigate if the process isn't decomposable, ie. if it can't do the same if at first applied in "one direction" and then in the other [eg. you can blur image by 1) computing average of neighbouring pixels, 2) blurring in horizontal and the vertical direction; option 2) has by a magnitude smaller complexity;; same "trick" is used for image resizing - stretched in one direction, then the other) | 
02-02-2005, 12:58 PM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,548
| | | Thanks, JustChecking,
- I was relieved that comments and definitions don't affect anything, so basically I can make it as pretty (or ugly) as I wish. I would have hated to have to make a compromise.
- I looked back over my script and there is a one-line function that gets called in every loop. I'll try putting that in line.
- The algorithm! You're right. I had to do some things in a pretty round-about way, and they're inside the loop. That's the most promissing place!
- As for un-nesting the loops, my two loops are vertical / horizontal sweeps and for this particular script they can't be done one after the other. I could do one big loop, but then I'd need a sort of end-of-line test which may slow things up - worth a shot though.
Thanks again,
Rô | 
02-02-2005, 03:03 PM
|  | Senior Member | | Join Date: Jul 2004 Location: Czech Rep.
Posts: 257
| | Quote: |
Originally Posted by byRo - As for un-nesting the loops, my two loops are vertical / horizontal sweeps and for this particular script they can't be done one after the other. I could do one big loop, but then I'd need a sort of end-of-line test which may slow things up - worth a shot though. | generally the rule of thumb is that number of nested loops has to be at most equal to dimension of data; which is obvious - you have to go through all the elements of the data...
that unnesting thing was more about the choice of algorithm... if you can post more details on what you wanna do, i (and others) could have a bit better look at it than in this abstract way... | 
02-03-2005, 07:22 AM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,548
| | Quote: |
Originally Posted by JustChecking ... if you can post more details on what you wanna do, i (and others) could have a bit better look at it than in this abstract way... | It's this little program + a very slow computer that got me wondering.
Rô | 
02-03-2005, 08:06 AM
|  | Senior Member | | Join Date: Jul 2004 Location: Czech Rep.
Posts: 257
| | Quote: |
Originally Posted by byRo | can't see any real reason for it to be slow...
my guesses are - executeAction() function is slow - switching between the script and action slows it down; and, more probably, everything in the fnTRANSFORM() is slow... but there's not that much to do about it...
and, add to it that java is generally slow, and here it has to be double-interpreted, so...
one advice would be to run PS in the debugger, start a profile and do proper timing, but that's work for whole afternoon if you want some results that would be of any help, and most probably in the end you'll know that PS is to blame | 
02-04-2005, 12:11 PM
| | Member | | Join Date: Aug 2004
Posts: 35
| | | Some optimizations.... Here is what I observed.
1) The condition expressions on both for loops contained division operations that really only need to be computed once before the loops start. I pulled those out. Probably not a big gain, but it doesn't hurt.
2) The call to fnSELECT reconstructs the same set of objects for each call. I reorganized the code so those objects are only set up once and the new COORD values are stuck in before each call to executeAction. I am making some assumptions here about how these classes are implemented, but this should work.
3) Math.random() is typically expensive, but I don't see any way to avoid calling it as often as you do.
4) the executeAction() operations are probably where the bulk of your time is being spent. Again, there is not a lot you can do to optimize this.
Profile the code. Beyond the slight gains that might be made from what I have mentioned above, I don't think there is a whole lot that can be done.
ciao,
-X | 
02-04-2005, 12:32 PM
| | Member | | Join Date: Aug 2004
Posts: 35
| | | Ooops.... I did some quick tests. Reusing the Action objects does not work. But it doesn't matter, nor does Math.random(). 99% of the execution time is within the executeAction call for fnSELECT.
The only way I can see to make this go faster is to figure out a way to have the SELECT action select more than one square at a time. Make one executeAction to select all of them at once. None of the JS optimizations really matter.
ciao,
-X | 
02-04-2005, 03:13 PM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,548
| | New version.... image here
Did some optimizing, tried to incorporate the tips in the thread:
- Changed the loops around and took some of the calculations out of the inner loop;
- Took out the function definitions and calls and used only methods (but still js keeps on forgetting the selection all the time!);
- General housekeeping and...
Didn't seem to make 1s of difference (actually seemed to take longer!)
I was sort of thinking about the selection part - maybe (not today) instead of making a new selection, and remembering that the size never changes, it would be quicker just to push the tile selection along (translate border).
Thanks, xbytor - interesting ideas!!
Rô | 
02-05-2005, 06:35 AM
|  | Senior Member | | Join Date: Jul 2004 Location: Czech Rep.
Posts: 257
| | Quote: |
Originally Posted by xbytor 1) The condition expressions on both for loops contained division operations that really only need to be computed once before the loops start. I pulled those out. Probably not a big gain, but it doesn't hurt. | that's an interesting idea, i'm not sure how this works in interpreted programs... i know that if all values that enter the expression are constants, or (in more advanced compilers) are not changed in the loop, the C/C++ compiler does this "compute and store" by itself...
i'll have to have a look at this in java... Quote: |
Originally Posted by xbytor 3) Math.random() is typically expensive, but I don't see any way to avoid calling it as often as you do. | unless random() in java is something special compared to rand() in C/C++, it takes one multiplication, one addition, and one modulo... calling the function, accessing the seed in memory, and returning from the function takes much longer that the whole generation of random number...
my guess would be also on the selection part... if i understood it correctly, making a selection in PS is equivalent to creating a mask, w/ all it's problems - allocating memory, filling it w/ black (or white), drawing in the selection, etc.
but i as well don't see any way to get over this... |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | All times are GMT -6. The time now is 08:34 PM. | |
|