Release v0.5 — more improvements#7
Conversation
WalkthroughVersion 0.5.0 release with zoom/pan display handling, Helicon Focus multi-stack workflow refactoring, unified preloading integrated with the prefetcher, PyTurboJPEG-accelerated JPEG decoding, memory-mapped I/O for prefetching, thread pool tuning, filesystem watcher event-handler refactoring, and QML zoom/pan with debounced resize. Changes
Sequence Diagram(s)sequenceDiagram
participant QML
participant UIState
participant AppCtrl
participant Prefetcher
QML->>UIState: setZoomed(true)
UIState->>AppCtrl: set_zoomed(true)
AppCtrl->>AppCtrl: is_zoomed = true
AppCtrl->>Prefetcher: cancel_all()
AppCtrl->>AppCtrl: clear image cache
AppCtrl->>UIState: emit zoom state signal
UIState->>QML: isZoomedChanged(true)
Note over QML: get_display_info short-circuited<br/>returns (0, 0, generation)
sequenceDiagram
participant QML
participant AppCtrl
participant HelicFocus
participant Sidecar
QML->>AppCtrl: launch_helicon()
AppCtrl->>AppCtrl: has_multiple_stacks?
alt Multiple stacks
AppCtrl->>AppCtrl: build per-stack raw file lists
else Single/No stack
AppCtrl->>AppCtrl: use selected RAWs
end
AppCtrl->>AppCtrl: _launch_helicon_with_files(file_list)
AppCtrl->>HelicFocus: launch_helicon_focus(files)
AppCtrl->>Sidecar: persist stacking metadata<br/>(stacked, stacked_date)
AppCtrl->>AppCtrl: clear stacks
sequenceDiagram
participant QML as Display
participant AppCtrl as AppController
participant Prefetcher
participant JPEG
QML->>AppCtrl: onDisplaySizeChanged (debounced)
AppCtrl->>AppCtrl: display_generation++
AppCtrl->>Prefetcher: cancel_all()
AppCtrl->>Prefetcher: start_prefetch(current_index)
Prefetcher->>Prefetcher: _decode_and_cache(image)
Prefetcher->>JPEG: decode_jpeg_resized (mmap I/O)
JPEG->>JPEG: TurboJPEG fast path<br/>(if available)
JPEG-->>Prefetcher: decoded image
Prefetcher-->>AppCtrl: emit progress
AppCtrl-->>QML: refresh UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Areas requiring extra attention:
Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai I made many of the changes you suggested for performance improvements. Analyze this debug log snippet and consider what the rest of the code is doing to see if further performance or functionality enhancements can be made - or if there is code that isn't doing what it is supposed to do. 2025-11-03 02:18:28,665 - main - INFO - Starting FastStack |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 92 🏁 Script executed: Length of output: 978 🏁 Script executed: Length of output: 2695 🏁 Script executed: Length of output: 1287 🏁 Script executed: Length of output: 1114 🏁 Script executed: Length of output: 4494 🏁 Script executed: Length of output: 1860 🏁 Script executed: Length of output: 9577 🏁 Script executed: Length of output: 102 🏁 Script executed: Length of output: 1048 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 203 🏁 Script executed: Length of output: 1646 🏁 Script executed: Length of output: 4793 @AlanRockefeller Great work on implementing the performance improvements! I've analyzed the debug log and identified several issues that are impacting performance: Critical Performance Issues1. Excessive
|
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
faststack/faststack/imaging/jpeg.py (1)
48-85: Turbo thumbnail path can exceedmax_dim.With very large images, even the smallest TurboJPEG scaling factor (e.g., 1/8) can leave the decoded array larger than
max_dim. Because_get_turbojpeg_scaling_factorreturns that factor and the Turbo path immediately returns the decoded array, callers receive thumbnails far bigger than requested, breaking the contract ofdecode_jpeg_thumb_rgb. Please clamp the Turbo result before returning—e.g., fall back to Pillow resizing when the decoded dimensions still exceedmax_dim.@@ - return jpeg_decoder.decode(jpeg_bytes, scaling_factor=scaling_factor, pixel_format=TJPF_RGB, flags=TJFLAG_FASTDCT) + decoded = jpeg_decoder.decode( + jpeg_bytes, + scaling_factor=scaling_factor, + pixel_format=TJPF_RGB, + flags=TJFLAG_FASTDCT, + ) + if decoded.shape[0] > max_dim or decoded.shape[1] > max_dim: + img = Image.fromarray(decoded) + img.thumbnail((max_dim, max_dim), Image.Resampling.LANCZOS) + return np.array(img) + return decoded @@ - return supported_factors[-1] if supported_factors else None + return supported_factors[-1] if supported_factors else None
🧹 Nitpick comments (1)
faststack/faststack/app.py (1)
396-407: Drop the unused callback parameter.Ruff’s ARG001 is right here—rename the argument so we don’t carry an unused binding.
- def _on_done(future): + def _on_done(_future):
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
faststack/ChangeLog.md(1 hunks)faststack/faststack/app.py(5 hunks)faststack/faststack/imaging/jpeg.py(4 hunks)faststack/faststack/imaging/prefetch.py(3 hunks)faststack/faststack/io/watcher.py(1 hunks)faststack/faststack/qml/Components.qml(1 hunks)faststack/faststack/qml/Main.qml(1 hunks)faststack/faststack/ui/provider.py(1 hunks)faststack/pyproject.toml(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
faststack/faststack/ui/provider.py (1)
faststack/faststack/app.py (1)
set_zoomed(93-103)
faststack/faststack/app.py (4)
faststack/faststack/imaging/prefetch.py (3)
cancel_all(115-121)update_prefetch(36-56)submit_task(58-69)faststack/faststack/ui/provider.py (1)
clear_all_stacks(166-167)faststack/faststack/io/helicon.py (1)
launch_helicon_focus(13-57)faststack/faststack/io/sidecar.py (2)
get_metadata(85-87)save(54-83)
🪛 LanguageTool
faststack/ChangeLog.md
[style] ~17-~17: Consider using a different verb for a more formal wording.
Context: ...he JPEG scaling factor calculation. - Fixed an issue where panning the image was no...
(FIX_RESOLVE)
[grammar] ~32-~32: Use a hyphen to join words.
Context: ...sion 0.4 ### Todo Make it use the full res image when zooming in When multiple ...
(QB_NEW_EN_HYPHEN)
🪛 Ruff (0.14.2)
faststack/faststack/imaging/jpeg.py
29-29: Redundant exception object included in logging.exception call
(TRY401)
38-38: Redundant exception object included in logging.exception call
(TRY401)
56-56: Redundant exception object included in logging.exception call
(TRY401)
65-65: Redundant exception object included in logging.exception call
(TRY401)
119-119: Redundant exception object included in logging.exception call
(TRY401)
137-137: Redundant exception object included in logging.exception call
(TRY401)
faststack/faststack/app.py
396-396: Unused function argument: future
(ARG001)
🔇 Additional comments (2)
faststack/faststack/imaging/prefetch.py (1)
20-26: Dynamic worker sizing looks good.The capped 2×CPU heuristic avoids oversubscription while still scaling decoding throughput, and it safely falls back when
os.cpu_count()is unavailable.faststack/faststack/ui/provider.py (1)
62-77: Zoom bridge wiring looks solid.The read-only property paired with
setZoomedcleanly forwards QML requests and emits the notify signal so bindings stay in sync.
[0.5.0] - 2025-11-03
Added
Changed
Fixed
ValueErrorinPyTurboJPEGcaused by unsupported scaling factors.AttributeErrorin the JPEG scaling factor calculation.Performance
PyTurboJPEGfor resized decoding.BILINEARresampling for large downscales.Summary by CodeRabbit
New Features
Bug Fixes
Improvements