I am going to answer my own question here. Sorry for the keyword soup in the title, but I wanted to make this very searchable for later, in case someone else has this question.
For context, when scripting in photoshop, the index of a layer it is offset by +1 if there is a background layer present. This can cause hard to track bugs if you don't realize it. Lot's of "It works on my file..." issues.
So far, I've discovered 4 methods to check for the presence of a background layer in order to account for that offset. I was curious about performance, so I wrote a quick test and results are... interesting.
Usually action manager code is lighting fast compared to the API, but in this case, when no background is present, the AM code is way slower!
In my case output with background:
Without background:
From now on, I will be using
For context, when scripting in photoshop, the index of a layer it is offset by +1 if there is a background layer present. This can cause hard to track bugs if you don't realize it. Lot's of "It works on my file..." issues.
So far, I've discovered 4 methods to check for the presence of a background layer in order to account for that offset. I was curious about performance, so I wrote a quick test and results are... interesting.
Usually action manager code is lighting fast compared to the API, but in this case, when no background is present, the AM code is way slower!
#target photoshop var timeStart = 0; var activeDocBGLyr = function() { try{ activeDocument.backgroundLayer; return true; }catch(e){ return false; } } var activeDocHasPropBGLyr = function() { return activeDocument.hasOwnProperty("backgroundLayer"); } var artLyrIsBG = function() { return activeDocument.artLayers[activeDocument.artLayers.length - 1].isBackgroundLayer ? 0 : 1; } var hasBackgroundAM = function () { var res = undefined;// jshint ignore:line try { var ref = new ActionReference(); ref.putProperty( 1349677170, 1315774496 ); ref.putIndex( 1283027488, 0 ); executeActionGet( ref ).getString( 1315774496 ); res = true; } catch ( e ) { res = false } return res; } timestart = $.hiresTimer; for (i=0;i<1000;i++) { activeDocBGLyr(); } $.writeln ("activeDocBGLyr(): "+ $.hiresTimer/1000000); timestart = $.hiresTimer; for (i=0;i<1000;i++) { activeDocHasPropBGLyr(); } $.writeln ("activeDocHasPropBGLyr(): "+ $.hiresTimer/1000000); timestart = $.hiresTimer; for (i=0;i<1000;i++) { artLyrIsBG(); } $.writeln ("artLyrIsBG(): "+ $.hiresTimer/1000000) timestart = $.hiresTimer; for (i=0;i<1000;i++) { hasBackgroundAM(); } $.writeln ("hasBackgroundAM(): "+ $.hiresTimer/1000000)
In my case output with background:
activeDocBGLyr(): 0.139192
activeDocHasPropBGLyr(): 0.106644
artLyrIsBG(): 5.53341
hasBackgroundAM(): 0.067161
Without background:
activeDocBGLyr(): 0.301541So for ease of use, legibility, and efficiency, the "hasOwnProperty" version seems to be the clear winner!
activeDocHasPropBGLyr(): 0.143729
artLyrIsBG(): 5.452488
hasBackgroundAM(): 5.955047
From now on, I will be using
activeDocument.hasOwnProperty("backgroundLayer")either wrapped as a function or just in-line.