perf: replace O(n²) lookups with Map/Dictionary indexes#205
Conversation
|
@coderabbitai full review |
Bundle ReportChanges will increase total bundle size by 86 bytes (0.0%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: viper-frontend-esmAssets Changed:
Files in
Files in
Files in
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #205 +/- ##
==========================================
+ Coverage 43.21% 43.47% +0.25%
==========================================
Files 894 894
Lines 51851 51857 +6
Branches 4844 4845 +1
==========================================
+ Hits 22406 22543 +137
+ Misses 28899 28766 -133
- Partials 546 548 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughFive files eliminate O(n) and O(n²) search patterns during data filtering, lookup, and grouping by precomputing Maps, Sets, and Dictionaries. Vue components optimize term and student resolution, while C# controllers optimize competency hierarchy construction and link grouping. ChangesLookup Performance Optimizations
🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Pull request overview
Improves performance across several endpoints/pages by replacing repeated linear searches with precomputed Map/Dictionary indexes, and updates CMS link grouping to avoid null-key dictionary failures.
Changes:
- CTS Competency hierarchy: replace per-item parent lookup (
FirstOrDefault) with anID -> DTOdictionary. - CMS grouped links: pre-index links by tag value via
GroupBy/ToDictionaryand filter out null tag values to preventDictionary<string, …>null-key exceptions. - Vue pages: replace repeated
.find()/.some()loops withMap/Setlookups.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/Areas/CTS/Controllers/CompetencyController.cs | Builds a Dictionary for O(1) parent lookups when constructing competency hierarchies. |
| web/Areas/CMS/Controllers/CMSLinkCollectionLinks.cs | Builds a tag-value index to order grouped link results efficiently; adds null filtering for dictionary keys. |
| VueApp/src/Students/pages/StudentClassYear.vue | Uses a Map keyed by personId to apply problem data without repeated .find(). |
| VueApp/src/Effort/pages/ScheduledCliWeeks.vue | Uses a Map keyed by termName to avoid repeated .find() per term column. |
| VueApp/src/CTS/pages/ManageMilestones.vue | Uses a Set of milestone competency IDs to filter competencies in O(n). |
The CMS grouped-links endpoint indexes links by tag value, and a
dictionary cannot key on null. Null-valued ("uncategorized") links are
appended after the grouped links so they are not dropped, preserving the
prior response while keeping the non-null lookups O(1).
| .ThenBy(c => c.Order) | ||
| .ToListAsync(); | ||
| var compHierarchy = new List<CompetencyHierarchyDto>(); | ||
| var allCompDtos = CtsMapper.ToCompetencyHierarchyDtos(comps); | ||
| var compsById = allCompDtos.ToDictionary(c => c.CompetencyId); |
| var links = await _context.Links | ||
| .AsNoTracking() |
| var allValues = await _context.LinkTags | ||
| .AsNoTracking() | ||
| .Where(lt => lt.LinkCollectionTagCategoryId == tagCategories.LinkCollectionTagCategoryId) |
Replaces O(n²) lookup patterns (nested
.find()/.some()/.Any()inside.map()/.forEach()/foreach) withMap/Set/Dictionaryindexes built once, then O(1) lookups in the loop.Prompted by The O(n²) bug that looked like clean code.
Changes
ManageMilestones.vue(CTS):Setof milestone competency IDsScheduledCliWeeks.vue(Effort): per-instructorMapkeyed by term nameStudentClassYear.vue(Students):Mapof students by person IDCompetencyController.cs(CTS):Dictionaryof competencies by ID for parent lookupCMSLinkCollectionLinks.cs(CMS):GroupBy/ToDictionaryof links by tag valueNotes
AsNoTracking().Tests
Adds backend tests for the competency hierarchy build (nesting + orphaned parent) and the CMS grouped-links ordering (grouping, de-dup, and the null-append path). The four CMS
DbSets are markedvirtualto allow NSubstitute mocking, mirroring the existing CTS context.