• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
3

P: SDK: Severe performance in developPresetFolder:getDevelopPresets ()

LEGEND ,
Jan 16, 2019 Jan 16, 2019

Copy link to clipboard

Copied

Ever since LR 7.3 introduced the new develop preset format, it takes O(n^2) time for a plugin to access all of the develop presets. Some users have 5K, 10K, or 15K presets, and it can take minutes for a plugin to access all of the presets:

for _, folder in ipairs (LrApplication.developPresetFolders ()) do 
    for _, preset in ipairs (folder:getDevelopPresets ()) do
        ...

Users think the plugin has crashed or hung! While having 10K presets may seem unusual, there's no excuse for LR to take minutes to return all the presets.

Here's how fast my LR / Mac OS loads presets versus the total number of presets:



Most likely, LR is storing all the presets in all the folders in a single flat list.  When the method folder:getDevelopPresets() is called, it scans the entire list for presets with a matching group.  The correct implementation is obvious: Use a hierarchical representation, with a list of folders, each folder with a list of presets.

Bug Fixed Locked
TOPICS
SDK

Views

1.2K

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
community guidelines

correct answers 1 Pinned Reply

Adobe Employee , Jun 29, 2023 Jun 29, 2023

This is an older bug that is no longer reproducible under the current Operating Systems and Lightroom versions. We are closing this bug. Should a similar bug arise, please create a new bug report. This thread will be closed.

Status Fixed

Votes

Translate

Translate
8 Comments
Enthusiast ,
Jan 16, 2019 Jan 16, 2019

Copy link to clipboard

Copied

John, they don't pay you enough for these bug reports. I do hope that Adobe has a plan for addressing them.

Votes

Translate

Translate

Report

Report
Explorer ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

Since reducing the number of preset to <2000 is an official recommendation on Adobes' support pages for opimtizing performance, I assume they do not consider this a bug: https://helpx.adobe.com/lightroom/kb/optimize-performance-lightroom.html (heading "Reduce the number of presets").

Votes

Translate

Translate

Report

Report
LEGEND ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

That help note is talking about a different issue, the cost of generating preview thumbnails for presets: 

"Adding presets to Lightroom (whether created by you or a third-party) can reduce performance because the Develop module generates thumbnails in the Navigator panel for each preset. This is most strongly seen once you have 2,000 or more presets. Reduce the number of presets loaded into Lightroom to only those you use most often to avoid this type of slow down." [Emphasis added]

That has no bearing on a blatant bug in the SDK API that causes the simple enumeration of the presets to slow down from milliseconds to minutes.   Internally, LR has no issue with enumerating thousands of presets, since it populates the Presets panel  nearly instantaneously even with 5,000 presets.

Further, that recommendation is long out-of-date, since LR (at least since 7.3) doesn't pre-generate Navigator thumbnail previews for presets when you first open a photo in Develop or make significant changes to the sliders (which would necessitate re-generation of the thumbnails).  Since at least LR 6, LR has been fast enough to generate full-sized previews on the fly as you hover the mouse over a preset.  My Any Preset plugin did that in LR 6, and Adobe introduced that functionality into LR 7.3, and that functionality works just as fast with 5000 presets as 5.

Confirming that, my LR 8.1 shows no difference in CPU utilization when opening a photo in Develop with 5000 presets versus 5 presets.

Votes

Translate

Translate

Report

Report
Adobe Employee ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

What is your use case of looping through every develop preset known by Lr? Do you just want to show the list in some UI? This SDK style of enumerating the presets is expensive because it needs to load and parse each preset from the disk, which could be slow.

If your use case are only interested in enumerating the presets to retrieve its metadata (name, path, uuid etc), it could be made fast. Once your plug-in has set its sight on a particular preset with its uuid, you can map to the actual preset settings pretty efficiently (because it only need to load only the presets that you're interested in. IOW, depending on your plug-in's use case, the up-front penalty to load all presets from the disk can or cannot be avoided. The current SDK implementation does not make this possible it seems. That should be addressed.






Votes

Translate

Translate

Report

Report
Adobe Employee ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

"Adding presets to Lightroom (whether created by you or a third-party) can reduce performance because the Develop module generates thumbnails in the Navigator panel for each preset. This is most strongly seen once you have 2,000 or more presets. Reduce the number of presets loaded into Lightroom to only those you use most often to avoid this type of slow down." 

This description is not accurate for desktop version of Lightroom (maybe true for Lr mobile). Lightroom desktop does not generate thumbnails previews for Navigator for each preset when you just switch to a new photo. It only load the full XMP preset and render it on-demand (lazily fashion) as one hovers the mouse over a preset. Switching the photos, just read the preset metadata which is optimized for fast access.

Votes

Translate

Translate

Report

Report
LEGEND ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

My Export LUT plugin displays the hierarchical list of presets, letting the user select one or more to export their develop settings as LUTs (see the screenshot below).  It just needs the folder and preset names for the entire list.

Here's example code:
local t = {}
for _, folder in ipairs (LrApplication.developPresetFolders ()) do
    for _, preset in ipairs (folder:getDevelopPresets ()) do
        table.insert (t, {folder = folder:getName (), 
            preset = preset:getName ()})
        end
    end
I don't think the cost of reading and parsing the .xmp files is related to this issue, since it appears that the SDK is already deferring the reading until preset:getSetting() is called.  I've verified this two ways:

1. Windows Process Monitor shows that the .xmp files aren't read by the code above. They're only read when preset:getSetting() is called.

2. Timing the code above and similar code that also calls preset:getSetting() shows a 5x increase in time per preset when preset:getSetting() is called (scripts below):




Also, the cost to read and parse should be O(n), directly proportional to the number of presets, not increasing as O(n^2), as is the case with getting the entire list of folder and preset names.

This problem only surfaced in 7.3 with the new preset format shared with ACR. I'd bet money that the new implementation of folder:getDevelopPresets() scans the entire list of in-memory presets, returning those whose group (folder) is equal to folder:getName().  Another hint that suggests this: The new .xmp format stores the group name in the .xmp file itself, and the directory structure is ignored, so the UI implementation may just create a flat list of all the presets, constructing the group structure on the fly.  The UI does this correctly, the SDK not.
--------------------------------------------------



--------------------------------------------------
local LrApplication = import "LrApplication"
local LrDate = import "LrDate"
local LrDialogs = import "LrDialogs"
local t, time = {}, LrDate.currentTime ()
for _, folder in ipairs (LrApplication.developPresetFolders ()) do
    for _, preset in ipairs (folder:getDevelopPresets ()) do
        table.insert (t, {folder = folder:getName (), 
            preset = preset:getName ()})
        end
    end
time = LrDate.currentTime () - time 
LrDialogs.message ("Folder name, preset name",
    "# presets = " .. #t .. "\ntime/preset = " .. time / #t)
--------------------------------------------------
local LrApplication = import "LrApplication"
local LrDate = import "LrDate"
local LrDialogs = import "LrDialogs"
local t, time = {}, LrDate.currentTime ()
for _, folder in ipairs (LrApplication.developPresetFolders ()) do
    for _, preset in ipairs (folder:getDevelopPresets ()) do
        table.insert (t, {folder = folder:getName (), 
            preset = preset:getName (), 
            settings = preset:getSetting ()})
        end
    end
time = LrDate.currentTime () - time 
LrDialogs.message ("Folder name, preset name, settings",
    "# presets = " .. #t .. "\ntime/preset = " .. time / #t)

Votes

Translate

Translate

Report

Report
Community Beginner ,
Aug 03, 2020 Aug 03, 2020

Copy link to clipboard

Copied

I have experienced this performance hit as well, in writing a plugin similar to John Ellis' . 

When getting all develop presets in order to loop over them and export processed versions of a selected image for each preset, the time to run the plugin does indeed go up exponentially proportional to the number of presets. 

It seems to be that John has diagnosed the problem correctly here, and the hints he's found make me suspect that same thing about the presets being internally stored as a flat list.

Votes

Translate

Translate

Report

Report
Adobe Employee ,
Jun 29, 2023 Jun 29, 2023

Copy link to clipboard

Copied

LATEST

This is an older bug that is no longer reproducible under the current Operating Systems and Lightroom versions. We are closing this bug. Should a similar bug arise, please create a new bug report. This thread will be closed.

Rikk Flohr: Adobe Photography Org
Status Fixed

Votes

Translate

Translate

Report

Report