Repository navigation
perf(cache): reuse decoded images for full-resolution previews and fix stale cache entries - #1959
Merged
Merged
Conversation
elhigu
force-pushed
the
perf/decoded-cache
branch
from
October 20, 2026 07:46
e67a191 to
7385039
Compare
Contributor
Author
|
Rebasedand fixed conflicts |
The decoded-image cache was keyed by path alone. A file rewritten under the same name, for example a tethered capture from a camera that reuses names like capt0000.nef, kept returning the old pixels. So did files decoded before a raw pre-processing setting changed: changing linearRawMode never cleared the cache, and a decode that finished after a settings change could put an image with the old settings back. Each entry now carries a fingerprint of the file's size and modification time and of the settings that change decoded pixels, also while the cache keeps it compacted. A lookup that no longer matches is a miss and drops the entry. Decoding moves into one helper, get_or_decode_pristine, which also makes concurrent requests for the same file share one decode instead of decoding it twice. load_image uses it, is_image_cached checks the fingerprint without expanding a compacted entry, and the background AI jobs check it before reusing a cached decode. Co-Authored-By: Claude Opus 5.5 <[email protected]>
generate_preview_for_path renders the full-resolution previews of the culling view, the collage modal and the tethering panel. It decoded the file from disk on every call. It now uses get_or_decode_pristine, so a file that is already decoded, for example because it is open in the editor, isn't decoded again, and a request that races the editor's own load shares its decode. The cached image is prepared with prepare_base_image_cow, which applies AI denoise, negative conversion and AI patches as before and borrows the image when none of them changes it. Nothing is compacted, so the photo open in the editor keeps full precision. A repeated full-resolution render took 556 ms -> 263 ms for a 12 MP raw and 1598 ms -> 886 ms for a 26 MP raw, with identical output. Co-Authored-By: Claude Opus 5.5 <[email protected]>
elhigu
force-pushed
the
perf/decoded-cache
branch
from
October 22, 2026 14:53
7385039 to
9be0104
Compare
Contributor
Author
|
rebased, fixed conflicts, updated benchmark numbers |
Owner
|
Thanks a lot for the PR, looks good to me. Also sorry for all the merge conflicts I've caused ;) |
elhigu
added a commit
to elhigu/RapidRAW
that referenced
this pull request
Oct 27, 2026
CyberTimon#1790 and CyberTimon#1959 are merged, and RapidRAW 1.6.7 does several of this fork's earlier fixes itself, so list only the fixes the fork still adds. The speedups are now measured against 1.6.7 with rapidraw bench on a 12 MP and a 26 MP raw, with identical output in every step. The recordings are marked as made on 1.6.5. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This is part 2 of the performance fixes listed in my fork's README; part 1, #1790, is merged. It is rebased on current
main(211ef55) and works with the new compacted decoded-image cache.The decoded-image cache had two problems:
capt0000.nef. So did images decoded before a raw pre-processing setting changed: changinglinearRawModenever cleared the cache, and a decode that finished after a settings change could put an image with the old settings back.generate_preview_for_pathdecoded the file from disk on every call, even when the photo was open in the editor.Where it makes the app faster
generate_preview_for_pathrenders the full-resolution previews of:imageCacheSizerecent ones (5 by default), within its memory limit.When the culling view and the editor ask for the same photo at the same time, it is now decoded once instead of twice.
Benchmark
Measured with the pipeline benchmark from my fork (
tools/pipeline-bench,rapidraw bench). It runs the app's own functions without a window, times each step and hashes its output.main(211ef55) andmainwith this PR, median of 5 runs each, on a 12 MP Sony A7S II raw and a 26 MP Sony a6700 raw with their edits:mainmaingenerate_preview_for_path)Full-resolution previews of a photo that is already decoded are 1.8-2.1x faster. Decoding, thumbnails, opening a photo, the first editor preview and export are unchanged within run-to-run noise, and every step's output is identical with and without this PR. Both builds ran with
MIMALLOC_ALLOW_THP=0so that allocator settings don't distort the comparison.Type of Change
Changes Made
get_or_decode_pristine, which also makes concurrent requests for the same file share one decode.load_imageuses it, after compacting the other entries as before,is_image_cachedchecks the fingerprint without expanding a compacted entry, and the background AI jobs check it before reusing a cached decode.generate_preview_for_pathusesget_or_decode_pristineand prepares the cached image withprepare_base_image_cow, so AI denoise, negative conversion and AI patches are applied exactly as before, and the cached image is borrowed instead of cloned when none of them changes it. It doesn't compact anything, so the photo open in the editor stays in full precision. For a photo the cache holds compacted, the preview uses that copy, the same as reopening the photo in the editor does.Trade-off: full-resolution previews now add their photos to the decoded-image cache, within its existing count and memory limits.
Screenshots/Videos
No UI changes.
Testing
Test Configuration:
Automated checks:
mainand with this PR.cargo fmt --checkandcargo clippy --all-targets --all-features -- -D warnings.test/decoded-cache-unit-tests) if you want them.Checklist
Additional Notes
Suggested release-notes bullet:
AI Disclaimer:
Please state the involvement of AI in this PR:
The code, measurements and this description are 100% AI-generated with Claude Code.
🤖 Generated with Claude Code