Perf: Replace ContainsKey + indexer with TryGetValue to eliminate redundant hash lookups#367
Open
PaulAndersonS wants to merge 2 commits into
Open
Perf: Replace ContainsKey + indexer with TryGetValue to eliminate redundant hash lookups#367PaulAndersonS wants to merge 2 commits into
PaulAndersonS wants to merge 2 commits into
Conversation
Eliminates redundant dictionary hash lookups by replacing the ContainsKey() + indexer[] anti-pattern with single TryGetValue() calls. Files changed: - Calendar/LoopingPannel/CustomSnapManager.cs (hot path during navigation) - Core/WindowOverlay/WindowOverlay.iOS.cs - Core/WindowOverlay/WindowOverlay.Windows.cs - Core/WindowOverlay/WindowOverlay.Android.cs Each occurrence previously computed the hash twice (once to check existence, once to retrieve the value). TryGetValue does both in a single lookup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace Items.ToList().FindAll() with Items.Where().ToList() and Items.ToList().FirstOrDefault() with Items.FirstOrDefault(). The original code copied the entire ObservableCollection into a new List before filtering. Since ObservableCollection<T> already implements IEnumerable<T>, LINQ can operate on it directly without the intermediate full copy. Files changed: - Accordion/SfAccordion.cs (3 occurrences) - Accordion/AccordionItemView.cs (1 occurrence) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Root Cause of the Issue
Multiple locations use the
Dictionary.ContainsKey()+dictionary[key]anti-pattern, which computes the hash and locates the bucket twice for every lookup. In hot paths (Calendar navigation, WindowOverlay positioning), this adds unnecessary overhead.Description of Change
Replaced all
ContainsKey+ indexer patterns with singleTryGetValue()calls, which perform the lookup once and return both existence and value in a single operation.Files changed:
maui/src/Calendar/LoopingPannel/CustomSnapManager.cs— Called during month/year view navigation (hot path)maui/src/Core/WindowOverlay/WindowOverlay.iOS.cs— Called during overlay child positioningmaui/src/Core/WindowOverlay/WindowOverlay.Windows.cs— Called during overlay child positioningmaui/src/Core/WindowOverlay/WindowOverlay.Android.cs— Called during overlay child positioningWhy This Matters
AddChildren()is called on every view navigation; the dictionary lookups happen per visible date groupAdditional Performance Opportunities Identified
.Where().Min/Max()in hot pathsItems.ToList().FindAll()unnecessary copyCast<T>().ToList().AsReadOnly()in GetVisualChildren.Where().ToList()for Min/Max calculationsnew PathF()allocation every draw frame.Cast<T>()in loops vs direct indexingConfigureAwait(false)in library asyncScreenshots
N/A — no visual changes (performance-only improvement)