Iteratively accessing PathItem.subPathItems[].pathPoints[] is super slow

Unless I’m doing something stupid (which is a distinct possibility), it seems to me that iteratively accessing anchor point values within a PathItem object is much slower than it should be. My use case is that I need to compile a list of all anchor points in a path so that I can create some custom layer masks for other layers in a document. My code works, but it’s way too slow, and when I do timing tests on different portions of my code the culprit is accessing PathItem.subPathItems[ ].pathPoints[ ]. Note that I’m running this as a UXP script, not in a UXP plugin.

Photoshop version: 26.3.0 (the latest - also tried in 25.12.1 with same issue)
Mac OS: 13.7.3 (not the latest), M1 silicon chip
UXP Developer Tools: 2.0.1 (not the latest, but the same issue occurs running the script from the File->Scripts->Browse menu in Photoshop).

To reproduce:

  1. Create a new Photoshop document, and add a text layer with some text (in this example, my text layer contains the text “THIS IS A LINE OF SOME TEXT”)
  2. Create a work path from the text layer (right click on the text layer, select 'Create Work Path’).
  3. Run the following code as a script:
let doc = require('photoshop').app.activeDocument;

let workPath = doc.pathItems.getByName('Work Path');
let points = [];
let numPoints=0;
let t1=Date.now();

for (var i=0;i<workPath.subPathItems.length;i++) { 
    for (var j=0;j<workPath.subPathItems[i].pathPoints.length;j++) { 
        points.push(workPath.subPathItems[i].pathPoints[j].anchor); 
        numPoints++;
    }
}

let t2=Date.now()-t1;

console.log('Num points: ' + numPoints + ', Total time: ' + t2 + ‘ms');

In my case, the following is printed to the console :

Num points: 814, 10723ms

So, it’s taking over 10 seconds just to access the anchor field of all points in a PathItem with only 814 points. That’s pretty long, and considering that my documents could have 50-100 paths where I need to get a list of points, that ends up being ~ 500-1000 seconds, which is on the order of 8-16 minutes per document. That’s way too slow.

Am I doing something stupid? Is there a better way to do this? Is this some inefficiency in the underlying PathItem/SubPathItem/PathPoint class implementations?

I appreciate any light anyone can shed on this.

DOM does not cache. Every property is getter except for IDs. It is best to extract all data from PS in one/few calls and then work with that cache you made. DOM has no api to do that. You would need batchplay. What you could do is to store items in variable instead calling full chain of getters every time.

1 Like

Thanks, Jarda, that worked perfectly, it’s now super fast. I guess it never occurred to me that I should use batchplay to access data that is accessible through the api.

1 Like

DOM doesn’t know your intentions. You could e.g. remove points in loop iteration number 200. Then stored data would be invalid if cached.

Not directly applicable, but every application should follow InDesign’s lead with regard to path points. This is more of a feature request.

InDesign has a path.entirePath property that gives you a way to get/set a path using an array of triples [[left_direction_x, right_direction_x],[anchor_x, anchor_y],[right_direction_x, right_direction_y]]. This is always much faster than setting paths path point by path point.

Illustrator has something somewhat similar, in that you can set anchor points–but not curve coordinates–using an array when creating a path. (If you can run a script long enough to get past the inevitable Illustrator scripting bugs/memory leaks.) It’s not the same.

It would be great if both Photoshop and Illustrator could adopt the path.entirePath property.

(Disclaimer: I worked on InDesign scripting while at Adobe.)

1 Like