mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-16 13:32:44 +00:00
# Description <!-- > Please provide a summary of the changes made in this PR. Include details such as: > * What issue does this PR address or fix? > * What new features or enhancements does this PR introduce? > * Are there any breaking changes or dependencies that need to be considered? --> Since #15438, every CLI run that loads a system preset spends about a second per preset file re-parsing that vendor's entire profile tree. A slice with a machine, process and filament preset got roughly 2.5 s slower, and a four-filament slice roughly 4 s slower. This PR loads each vendor tree once per run instead. Resolved presets and G-code are unchanged. The GUI never takes this path, and no release contains #15438, so the regression only affects CLI runs on current dev and nightly builds. That includes print farms, slicing services and plugins that call `orca-slicer --slice`, and CI suites. ## Changes ### Why it was slow `PresetBundle::resolve_preset_config` resolves a system preset through its vendor manifest by loading the whole OrcaFilamentLibrary bundle and the whole vendor tree from JSON, then picking the one preset out. The CLI did that separately for every `--load-settings` and `--load-filaments` file, on a fresh `PresetBundle` each time. With BBL presets, a machine + process + filament run opened `BBL.json` three times and read BBL's 2,879 profile files and the library's 512 three times over. ### Load each vendor tree once - `PresetBundle` keeps every vendor bundle its manifest path loads, keyed by source root, vendor and substitution rule, and reuses them for later resolutions on the same bundle. - OrcaFilamentLibrary is cached the same way, so vendors under one root share a single library load and the library's own presets resolve from that same instance. A vendor bundle only reads from its base while loading, so sharing it is safe. - A failed or throwing load is not kept, so error reporting is unchanged. - The key includes the source root, so presets from two different profile roots still resolve separately. - The CLI resolves every system preset through one `PresetBundle` for the whole run, instead of creating one per file. The resolved configurations still come from the same canonical vendor loader, so what a preset resolves to does not change. Only the CLI calls `resolve_preset_config`, so a long-lived GUI bundle cannot end up holding profile trees that later change on disk. # Screenshots/Recordings/Graphs <!-- > Please attach relevant screenshots to showcase the UI changes. > Please attach images that can help explain the changes. --> CLI slice of a 20 mm cube with X1 Carbon system presets. Both builds get the same datadir, best of 3, Linux. "Before" is this PR's base from CI. | System presets loaded | Before | After | |---|---|---| | machine | 0.95 s | 0.87 s | | machine + process | 1.67 s | 0.92 s | | machine + process + 1 filament | 2.51 s | 0.97 s | | machine + process + 4 filaments | 5.00 s | 0.99 s | Files opened during the machine + process + filament run (`strace -e openat`): | | Before | After | |---|---|---| | `BBL.json` | 3 | 1 | | `OrcaFilamentLibrary.json` | 3 | 1 | | `system/BBL/**/*.json` | 8,634 | 2,880 | | `system/OrcaFilamentLibrary/**/*.json` | 1,536 | 512 | Peak memory did not rise: max RSS 306 MB → 286 MB for the three-preset run, and 305 MB → 285 MB for four filaments. The "before" figure is an AppImage, so part of that gap is probably packaging. ## Tests <!-- > Please describe the tests that you have conducted to verify the changes made in this PR. --> - New test "Manifest-backed resolution reuses the vendor tree it already loaded" in `tests/libslic3r/test_preset_bundle_loading.cpp`. It resolves one preset, changes the parent profile on disk, then resolves a sibling. The same bundle returns the value it already loaded, and a fresh bundle picks up the change. - New test "Manifest-backed resolution shares the library between vendors under one root". It resolves through one vendor, changes a library profile on disk, then resolves through a second vendor and a library preset on the same bundle. Both return the value already loaded, and a fresh bundle picks up the change. - All `[Preset][Bundle]` tests pass (87 test cases, 1,069 assertions), including the existing manifest-backed resolution cases for source-root scoping, malformed vendor loads, missing parents and type mismatches. - G-code of the three-preset slice is identical before and after, header lines excluded. - The external CLI regression suite passes. Two cases report as unexpectedly passing because #15639 fixed their bug. They pass the same way on this PR's base without the change. - A GUI-vs-CLI parity run over 10 fixtures shows no new differences. - Builds clean on Linux (Release, with tests). <!-- > A guide for users on how to download the artifacts from this PR. --> [How to Download Pull Requests Artifacts for Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)