Copy link to clipboard
Copied
Hello!
Why does the same script (ExtendScript) on Indesign server take 10 times longer than on local Indesign (both Windows)?
Is there a way to improve speed?
Thanks in advance.
It depends.
If you invoke the script via SOAP and it is short running, the SOAP overhead may be it.
You might have too fat startup scripts, or too many of them, while using the transient "main" session that executes them on each run. On a Mac IDS I once cured a slow startup situation by tracking down a recursion in the startup scripts folder hierarchy caused by a bad alias, only interrupted when the max path length was exceeded. On the way, I also removed some unused stock scripts, got me almost
...Copy link to clipboard
Copied
Hi,
We would probably need to see the script, and documents, to be able to give a opinion, or at least now what the script is supposed to be doing?
Regards
Malcolm
Copy link to clipboard
Copied
True. I thought that being the same script on local and on server. The problem would be configuration or something similar.
Anyway I have managed to reduce the times by modifying the code. It could probably be improved further but it is already acceptable.
Thanks for answering!
Copy link to clipboard
Copied
If you have installed on your InDesign Server on Virtual machine, then you need to check your virtual machine's configuration.
And need to check for memory consumptions. That will also be dependent on number of session you are running at once.
You should keep a watch on memory consumption of virtual machine.
Best
Sunil
Copy link to clipboard
Copied
No. It is on a Windows Server 2019 Standard.
Anyway I have managed to reduce the times by modifying the code. It could probably be improved further but it is already acceptable.
Thanks for answering!
Copy link to clipboard
Copied
It depends.
If you invoke the script via SOAP and it is short running, the SOAP overhead may be it.
You might have too fat startup scripts, or too many of them, while using the transient "main" session that executes them on each run. On a Mac IDS I once cured a slow startup situation by tracking down a recursion in the startup scripts folder hierarchy caused by a bad alias, only interrupted when the max path length was exceeded. On the way, I also removed some unused stock scripts, got me almost immediate startup.
How many fonts are installed, are they both on the same machines?
Do you use $.writeln console output, or $.bp() without ESTK around - can be slow like molasses.
Last time I looked, ExtendScript also had several ways to cause memory leaks. Have you included "modern" JS code style, e.g. closures? If so, How frequently do you restart your server?
There are many more possible reasons, many anecdotes to forget. When you permanently work on your code base, you may notice a sudden jump, comparing to previous test runs. Investigate as soon you notice them, revisit your recent changes.
Afterwards, I've seen optimizations of big scripts take weeks or months even in a team effort. Refactoring object sizes, reduce use of globals, rework XML xpaths.
In general, use the ESTK profiler if and as long it works - it may choke on a script exceeding few 100k code lines, solved by writing my own profiler. With good metrics you at least know what to optimize.
Again, there is no silver bullet. When you see the trouble spots, there are so many ways to improve speed, one could write a book on them and sell 5 copies. Kris is introducing some basics right now in the Developer's section of the CreativePro week (an online event).
As I said this is old memory, nowadays in the rare case that I do scripting at all, I prefer a different scripting engine (Google V8 via plug-in) where you have different profiling tools, memory usage and so forth. Same as above, know your tools.
Copy link to clipboard
Copied
I effectively invoke the script via SOAP. So overhead and/or sessions might well be the cause or one of them.
Although I have been able to improve performance by making changes to the code; I will check that and if I can or have time I would like to try the other options (such as plugins) that possibly perform better.
Thank you very much Dirk_Becker for your answer.
Copy link to clipboard
Copied
Let's not just close this thread. As you were asking for concrete ways to improve speed, please also describe your solution.
Here I'll also add a few more points, maybe some more contributors will join?
E.g. passing around lengthy ExtendScript XML as argument is slow.
Arbitrary depth Xpath queries "//SomeTag" or XML rules on document embedded XML are slow, try to work from sub-roots if your data model permits.
Reduce the number of property slots per prototype (e.g. below 100), better use sub-objects.
Reduce the number of globals.
Copy link to clipboard
Copied
Your
var ranges = para.textStyleRanges;
is another candidate for optimization. It is a native object where accessing the length property and accessing the individual items causes native operations. Try
var ranges = para.textStyleRanges.everyItem().getElements();
Anyway, you mentioned that the log line improves the speed. Unusual except that the logged expression does not make a sense, and may even cause an exception - therefor the shorter execution time. The "ranges" collection itself does not have the property "contents", only the individual items have. You can grab all of them at once with
var allContents = para.textStyleRanges.everyItem().contents;
which is an array of strings – most of the time. You are also not dealing with the special case that a contents property holds a SpecialCharacter enum rather than a string.
Edit: textStyleRanges.getElements() was nonsense, thanks Peter, inserted the everyItem(). I definitely have done too few scripting in years.
Copy link to clipboard
Copied
Adding to Dirk's comment, similarly, instead of
var rCharacters = ranges[r].characters;
use
var rCharacters = ranges[r].characters.everyItem().getElements();
or, to squeeze out another microsecond, use
var rCharacters = ranges[r].characters.everyItem().getElements().slice(0);
Furthermore, instead of
var endPoint = para.characters[para.characters.length - 1].insertionPoints[1].index;
use
var endPoint = para.insertionPoints[-1].index;
which is one call fewer to the object model.
Peter
Copy link to clipboard
Copied
I've only recently - in Kris' session - come across that slice(0) optimization and still wonder why it changes anything beyond adding time. This indicates that the JS array returned by getElements() is suboptimal comparing to the copy produced by slice(0).
Copy link to clipboard
Copied
In truth, adding .slice(0) makes makes only very little difference.
Copy link to clipboard
Copied
Thank you Dirk_Becker and Peter_Kahrel
I will make those changes. Every milisecond is wolcome!