Skip to content

fix: performance improvements (#312) - #356

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/performance-312
May 14, 2026
Merged

fix: performance improvements (#312)#356
laurentiu021 merged 1 commit into
mainfrom
fix/performance-312

Conversation

@laurentiu021

@laurentiu021 laurentiu021 commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses 5 of 6 performance issues from the code review (PERF-002/004/005/008).

Changes

  1. DuplicateFileService + LargeFileScanner (PERF-002) — replaced ToLowerInvariant() + Contains() with OrdinalIgnoreCase comparison. Eliminates string allocation on every directory path during traversal.
  2. SpeedTestService (PERF-004) — SHA-256 hashing now uses File.OpenRead() stream instead of File.ReadAllBytes(). Avoids loading entire zip into memory.
  3. ProcessManagerService (PERF-005) — p.MainModule cached once per process instead of accessed twice. Halves P/Invoke overhead.
  4. AboutViewModel (PERF-008) — CopyEnvironmentInfo WMI queries moved to Task.Run background thread. UI no longer freezes during collection.

Not addressed (lower priority, separate PR)

  • PERF-003: ObservableCollection bulk-update (6 VMs, more invasive)
  • PERF-007: FontFamily per code inline (MarkdownTextBlock)

Closes #312

Summary by CodeRabbit

  • Chores

    • Released version 0.48.5 with performance and security improvements.
  • Performance

    • Optimized memory usage during file integrity verification.
    • Improved case-insensitive path handling across file scanning operations.
    • Moved environment data collection off the UI thread for better responsiveness.
    • Streamlined process retrieval logic.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

PR 356 implements five localized performance and threading improvements: case-insensitive path comparisons without allocation overhead, consolidated process module access, streaming file hashing, and async environment info collection to prevent UI blocking.

Changes

Performance and Threading Optimizations

Layer / File(s) Summary
Case-insensitive path matching without allocation
SysManager/SysManager/Services/DuplicateFileService.cs, SysManager/SysManager/Services/LargeFileScanner.cs
Both services now use StringComparison.OrdinalIgnoreCase on direct path strings, eliminating per-path ToLowerInvariant() allocation during skip-segment checks.
Process snapshot module consolidation
SysManager/SysManager/Services/ProcessManagerService.cs
ProcessEntry Description and FilePath are now retrieved together from a single MainModule access inside one try block, replacing prior per-property exception handling.
Streaming SHA-256 hashing
SysManager/SysManager/Services/SpeedTestService.cs
Ookla zip integrity hash is computed via File.OpenRead stream instead of File.ReadAllBytes, avoiding full file load into memory.
Async environment collection and clipboard operations
SysManager/SysManager/ViewModels/AboutViewModel.cs
New CopyEnvironmentInfoAsync command runs environment collection on a background task, then sets clipboard and status; CollectEnvironmentInfo now returns text and handles WMI/operation exceptions internally via return values.
Release documentation
CHANGELOG.md
Version 0.48.5 entry documents all five optimization improvements.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • laurentiu021/SystemManager#294: Shares modifications to ProcessManagerService process snapshot logic and SpeedTestService SHA-256 hash computation for Ookla download validation.

Poem

🐰 A rabbit hops through performance land,
Trimming allocations with a swift hand—
No more lowercasing every path with care,
And WMI queries breathe fresher air!
Streams hash files without greed,
Small optimizations fulfilling the need. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: performance improvements (#312)' directly matches the pull request objective of addressing five performance items and is specific enough to identify the main change.
Linked Issues check ✅ Passed The PR successfully implements four of six performance requirements (PERF-002, PERF-004, PERF-005, PERF-008) with code changes; PERF-003 and PERF-007 are acknowledged as deferred and are non-blocking per PR objectives.
Out of Scope Changes check ✅ Passed All changes align with the linked issue #312 performance objectives: case-insensitive comparisons (PERF-002), stream hashing (PERF-004), module caching (PERF-005), and moving WMI queries off UI thread (PERF-008).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/performance-312

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 19.04762% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
SysManager/SysManager/ViewModels/AboutViewModel.cs 0.00% 15 Missing ⚠️
...nager/SysManager/Services/ProcessManagerService.cs 50.00% 0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SysManager/SysManager/ViewModels/AboutViewModel.cs`:
- Around line 220-237: The method CopyEnvironmentInfoAsync currently sets
UpdateStatus to success unconditionally; update it to only set the success
message after a confirmed successful Clipboard.SetText call, and handle failure
paths: call CollectEnvironmentInfo() and if it returns null/empty or an
error-indicating string (handle the known error format your
CollectEnvironmentInfo returns) set UpdateStatus to an error message and skip
Clipboard.SetText; wrap Clipboard.SetText in the existing catch for
System.Runtime.InteropServices.ExternalException but set UpdateStatus to a
failure message (including ex.Message) instead of leaving the success text; keep
the existing catches for ManagementException and InvalidOperationException but
ensure they set appropriate UpdateStatus values as currently done.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bdfade6a-e10b-4f3e-a7c5-79ad8b49e08e

📥 Commits

Reviewing files that changed from the base of the PR and between 656f071 and 3975bfe.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • SysManager/SysManager/Services/DuplicateFileService.cs
  • SysManager/SysManager/Services/LargeFileScanner.cs
  • SysManager/SysManager/Services/ProcessManagerService.cs
  • SysManager/SysManager/Services/SpeedTestService.cs
  • SysManager/SysManager/ViewModels/AboutViewModel.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build & unit tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (5)
SysManager/SysManager/Services/DuplicateFileService.cs (1)

229-229: LGTM!

SysManager/SysManager/Services/LargeFileScanner.cs (1)

128-128: LGTM!

SysManager/SysManager/Services/SpeedTestService.cs (1)

300-301: LGTM!

CHANGELOG.md (1)

9-21: LGTM!

SysManager/SysManager/Services/ProcessManagerService.cs (1)

74-79: LGTM!

Comment on lines +220 to +237
private async Task CopyEnvironmentInfoAsync()
{
try
{
var text = await Task.Run(() => CollectEnvironmentInfo()).ConfigureAwait(true);
try { Clipboard.SetText(text); }
catch (System.Runtime.InteropServices.ExternalException ex) { Log.Debug("Clipboard locked: {Error}", ex.Message); }
UpdateStatus = "Environment info copied to clipboard.";
}
catch (System.Management.ManagementException ex)
{
UpdateStatus = $"Couldn't collect environment info: {ex.Message}";
}
catch (InvalidOperationException ex)
{
UpdateStatus = $"Couldn't collect environment info: {ex.Message}";
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix false-success status when clipboard copy fails.

UpdateStatus is set to success even when Clipboard.SetText throws, so users can get a “copied” message without data actually copied. Also, because CollectEnvironmentInfo() returns error text instead of throwing, this method should explicitly handle that return path before claiming success.

💡 Suggested fix
 private async Task CopyEnvironmentInfoAsync()
 {
-    try
-    {
-        var text = await Task.Run(() => CollectEnvironmentInfo()).ConfigureAwait(true);
-        try { Clipboard.SetText(text); }
-        catch (System.Runtime.InteropServices.ExternalException ex) { Log.Debug("Clipboard locked: {Error}", ex.Message); }
-        UpdateStatus = "Environment info copied to clipboard.";
-    }
-    catch (System.Management.ManagementException ex)
-    {
-        UpdateStatus = $"Couldn't collect environment info: {ex.Message}";
-    }
-    catch (InvalidOperationException ex)
-    {
-        UpdateStatus = $"Couldn't collect environment info: {ex.Message}";
-    }
+    var text = await Task.Run(CollectEnvironmentInfo).ConfigureAwait(true);
+    if (text.StartsWith("Couldn't collect environment info:", StringComparison.Ordinal))
+    {
+        UpdateStatus = text;
+        return;
+    }
+
+    try
+    {
+        Clipboard.SetText(text);
+        UpdateStatus = "Environment info copied to clipboard.";
+    }
+    catch (System.Runtime.InteropServices.ExternalException ex)
+    {
+        Log.Debug("Clipboard locked: {Error}", ex.Message);
+        UpdateStatus = "Couldn't copy environment info: clipboard is currently in use.";
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/AboutViewModel.cs` around lines 220 - 237,
The method CopyEnvironmentInfoAsync currently sets UpdateStatus to success
unconditionally; update it to only set the success message after a confirmed
successful Clipboard.SetText call, and handle failure paths: call
CollectEnvironmentInfo() and if it returns null/empty or an error-indicating
string (handle the known error format your CollectEnvironmentInfo returns) set
UpdateStatus to an error message and skip Clipboard.SetText; wrap
Clipboard.SetText in the existing catch for
System.Runtime.InteropServices.ExternalException but set UpdateStatus to a
failure message (including ex.Message) instead of leaving the success text; keep
the existing catches for ManagementException and InvalidOperationException but
ensure they set appropriate UpdateStatus values as currently done.

@laurentiu021
laurentiu021 merged commit b5cb7a6 into main May 14, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the fix/performance-312 branch May 14, 2026 10:21
laurentiu021 added a commit that referenced this pull request May 22, 2026
Add CHANGELOG entry for v0.28.8 — Process Manager Open file location fix
+ Show only apps toggle.

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
laurentiu021 added a commit that referenced this pull request May 22, 2026
…nModule cache, async WMI (#312) (#356)

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Performance — ToLowerInvariant, ObservableCollection bulk-update, stream hashing, MainModule cache

2 participants