Script takes longer and longer when accessing individual pathPoint objects.

New Here ,
Feb 11, 2020

Copy link to clipboard

Copied

I wrote a test script after noticing that my scripts were taking longer to run each successive time. My guess was that accessing individual path points on a pathItem was the cause and it seems that I was right.

 

The following script simply iterates through all the path points in all the path items of the active doc. It does this 50 times in a row. After each iteration of the main loop the time increases. The first iteration takes 103ms. The 50th iteration takes 4391ms. The script doesn't add anything to the document or modify it. It simply queries the pathPoint.anchor property for each path point.

 

#target illustrator

var executionTimes = [];
var timeDifferentials = [];

for(var counter = 0; counter < 50; counter++)
{
    var start = new Date().getTime();
    var allShapes = [];
    for(var i = 0; i < app.activeDocument.pathItems.length; i++)
    {
        var curPI = app.activeDocument.pathItems[i];
        allShapes.push(curPI);
    }
    
    for(var i = 0; i < allShapes.length; i++)
    {
        var curPI = allShapes[i];
        for(var j = 0; j < curPI.pathPoints.length; j++)
        {
            curPathPoint = curPI.pathPoints[j];
            var curPointLocation = curPathPoint.anchor;
        }
    }
    var end = new Date().getTime();
    var time = end - start;    
    executionTimes.push(time);
    if(counter > 0)
    {
        timeDifferentials.push(time - executionTimes[counter - 1]);
    }
}

Below is a list of the execution times as recorded during the script

103,150,236,319,436,531,629,732,822,933,1018,1213,1424,1392,1398,1648,1606,1740,1859,1917,1937,1957,2185,2234,2283,2424,2467,2705,2584,2708,2801,2839,2996,3078,3174,3200,3355,3474,3426,3614,3789,3822,3818,3977,4062,4048,4251,4316,4406,4391

 

If I comment out the second line below, the execution times reduce drastically but they still increase with each iteration. However, if I comment out both the iteration times do NOT increase. they stay constnatly around 4ms.

curPathPoint = curPI.pathPoints[j];
var curPointLocation = curPathPoint.anchor;

 

Interestingly, if I run the script a second time on the same document without closing it, the first iteration takes longer than the last iteration of the first time I ran the script. However, if I save the doc, close illustrator, and then reopen the doc the script starts out at ~100ms again.

 

I don't really understand what's happening under the hood, maybe the DOM is holding on to cached data? Does anybody know a way to flush out any cached data through the javascript interface? It's troublesome to reopen illustrator every time I need to run my scripts again.

 

Adobe Community Professional
Correct answer by DilliamWowling | Adobe Community Professional

we are plagued by seemingly inexplicable memory issues with regards to scripting illustrator.

 

one of the tactics of which many of us have made a habit is to avoid declaring variables inside of loops... I can't really speak to why it helps, but in my own anecdotal experience, it does seem to prevent (or at least diminish) some of these kinds of issues.

 

So just declare your variables before loop, then assign the value inside the loop.

 

The other big issue i can see is that you're accessing items from the Document scope. This can cause a whole host of problems because of the way items are stored in that scope. It's always a good idea to try to use a narrower scope (like Layer or GroupItem). This can and does increase complexity in your script, but i promise you it's worth it. 

 

Let me know if you have any specific questions or anything. It seems like you're decently proficient, but I'm more than happy to help further if this wasn't clear.

TOPICS
Performance, Scripting, SDK

Views

456

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Script takes longer and longer when accessing individual pathPoint objects.

New Here ,
Feb 11, 2020

Copy link to clipboard

Copied

I wrote a test script after noticing that my scripts were taking longer to run each successive time. My guess was that accessing individual path points on a pathItem was the cause and it seems that I was right.

 

The following script simply iterates through all the path points in all the path items of the active doc. It does this 50 times in a row. After each iteration of the main loop the time increases. The first iteration takes 103ms. The 50th iteration takes 4391ms. The script doesn't add anything to the document or modify it. It simply queries the pathPoint.anchor property for each path point.

 

#target illustrator

var executionTimes = [];
var timeDifferentials = [];

for(var counter = 0; counter < 50; counter++)
{
    var start = new Date().getTime();
    var allShapes = [];
    for(var i = 0; i < app.activeDocument.pathItems.length; i++)
    {
        var curPI = app.activeDocument.pathItems[i];
        allShapes.push(curPI);
    }
    
    for(var i = 0; i < allShapes.length; i++)
    {
        var curPI = allShapes[i];
        for(var j = 0; j < curPI.pathPoints.length; j++)
        {
            curPathPoint = curPI.pathPoints[j];
            var curPointLocation = curPathPoint.anchor;
        }
    }
    var end = new Date().getTime();
    var time = end - start;    
    executionTimes.push(time);
    if(counter > 0)
    {
        timeDifferentials.push(time - executionTimes[counter - 1]);
    }
}

Below is a list of the execution times as recorded during the script

103,150,236,319,436,531,629,732,822,933,1018,1213,1424,1392,1398,1648,1606,1740,1859,1917,1937,1957,2185,2234,2283,2424,2467,2705,2584,2708,2801,2839,2996,3078,3174,3200,3355,3474,3426,3614,3789,3822,3818,3977,4062,4048,4251,4316,4406,4391

 

If I comment out the second line below, the execution times reduce drastically but they still increase with each iteration. However, if I comment out both the iteration times do NOT increase. they stay constnatly around 4ms.

curPathPoint = curPI.pathPoints[j];
var curPointLocation = curPathPoint.anchor;

 

Interestingly, if I run the script a second time on the same document without closing it, the first iteration takes longer than the last iteration of the first time I ran the script. However, if I save the doc, close illustrator, and then reopen the doc the script starts out at ~100ms again.

 

I don't really understand what's happening under the hood, maybe the DOM is holding on to cached data? Does anybody know a way to flush out any cached data through the javascript interface? It's troublesome to reopen illustrator every time I need to run my scripts again.

 

Adobe Community Professional
Correct answer by DilliamWowling | Adobe Community Professional

we are plagued by seemingly inexplicable memory issues with regards to scripting illustrator.

 

one of the tactics of which many of us have made a habit is to avoid declaring variables inside of loops... I can't really speak to why it helps, but in my own anecdotal experience, it does seem to prevent (or at least diminish) some of these kinds of issues.

 

So just declare your variables before loop, then assign the value inside the loop.

 

The other big issue i can see is that you're accessing items from the Document scope. This can cause a whole host of problems because of the way items are stored in that scope. It's always a good idea to try to use a narrower scope (like Layer or GroupItem). This can and does increase complexity in your script, but i promise you it's worth it. 

 

Let me know if you have any specific questions or anything. It seems like you're decently proficient, but I'm more than happy to help further if this wasn't clear.

TOPICS
Performance, Scripting, SDK

Views

457

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Feb 11, 2020 0
Adobe Community Professional ,
Feb 12, 2020

Copy link to clipboard

Copied

we are plagued by seemingly inexplicable memory issues with regards to scripting illustrator.

 

one of the tactics of which many of us have made a habit is to avoid declaring variables inside of loops... I can't really speak to why it helps, but in my own anecdotal experience, it does seem to prevent (or at least diminish) some of these kinds of issues.

 

So just declare your variables before loop, then assign the value inside the loop.

 

The other big issue i can see is that you're accessing items from the Document scope. This can cause a whole host of problems because of the way items are stored in that scope. It's always a good idea to try to use a narrower scope (like Layer or GroupItem). This can and does increase complexity in your script, but i promise you it's worth it. 

 

Let me know if you have any specific questions or anything. It seems like you're decently proficient, but I'm more than happy to help further if this wasn't clear.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 12, 2020 1
Adobe Community Professional ,
Feb 13, 2020

Copy link to clipboard

Copied

check this out.

 

#target illustrator

var executionTimes = [];
var timeDifferentials = [];

var allShapes = [];
for(var i = 0; i < app.activeDocument.pathItems.length; i++)
{
    var curPI = app.activeDocument.pathItems[i];
    allShapes.push(curPI);
}

for(var counter = 0; counter < 50; counter++)
{
    var start = new Date().getTime();
    
    for(var i = 0; i < allShapes.length; i++)
    {
        var curPI = allShapes[i];
        for(var j = 0; j < curPI.pathPoints.length; j++)
        {
            curPathPoint = curPI.pathPoints[j];
            var curPointLocation = curPathPoint.anchor;
        }
    }
    var end = new Date().getTime();
    var time = end - start;    
    executionTimes.push(time);
    if(counter > 0)
    {
        timeDifferentials.push(time - executionTimes[counter - 1]);
    }
}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 13, 2020 1
Adobe Community Professional ,
Feb 13, 2020

Copy link to clipboard

Copied

obviously follow William's excelent advise on top of that.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 13, 2020 2
New Here ,
Feb 14, 2020

Copy link to clipboard

Copied

Thanks for the help 🙂 I'll definitely use your advice in the future.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 14, 2020 0
Adobe Community Professional ,
Feb 14, 2020

Copy link to clipboard

Copied

So i've thought about this a whole lot.. But it wasn't until just now that I felt like i might actually have a grasp on WHY this issue of variable declarations inside of loops is an issue here. It's been known for a while that the garbage collector ($.gc()) does virtually nothing (at least nothing noticeable as far as i've seen).. So I'm wondering whether there's just a systemic issue with clearing out old unused variables..

 

I wonder if the issue is that each time the loop runs, a new instance of the variable is created, and then each time the script has to access that variable, it's like searching through a list of old variables with the same name (instead of the new variable effectively overwriting the old one). So each time through the loop, the list gets longer and the script has to try and access each of those old versions and determine whether it's the current one?? And then perhaps the script occasionally fails to actually find the correct "version" of that variable, which leads to the MRAP/PARM errors where the object properties are no longer available because that particular "version" was overwritten, but not succesfully removed from the equation?

 

Admittedly i know little to nothing about how ExtendScript (or JavaScript for that matter) works under the hood.. But there does seem to be a direct correlation between the number of times you declare the same variable and the amount of time it takes to access the information stored in that variable.

 

idk. just thinking out loud..

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 14, 2020 2
Adobe Community Professional ,
Feb 14, 2020

Copy link to clipboard

Copied

you might be on to something, it makes a lot of sense.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 14, 2020 1
Silly-V LATEST
Adobe Community Professional ,
Feb 14, 2020

Copy link to clipboard

Copied

Sounds reasonable, but the only way we'd ever know for sure is if the developers of Illustrator will descend from Mt Olympus and tell us what's up with all that.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 14, 2020 2
Resources