Skip to content

Optimize pack load performance (~7.8s to <1s) - #38

Merged
emosaru merged 2 commits into
avaloniafrom
claude/hungry-jones
Apr 13, 2026
Merged

Optimize pack load performance (~7.8s to <1s)#38
emosaru merged 2 commits into
avaloniafrom
claude/hungry-jones

Conversation

@emosaru

@emosaru emosaru commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Pack load performance optimizations

  • Dictionary index for persistable references: Replace O(n) List.IndexOf in GetPersistableLocationReference/GetPersistableItemReference with O(1) dictionary lookup. Eliminates ~2.9s of O(n²) work during voice command building (583 location lookups).
  • Defer voice command map to background thread: BuildCommandMap (~5s) now snapshots item/location data and runs on Task.Run() with cancellation support, completely off the main thread critical path.
  • Code→provider index in ItemDatabase: BuildCodeIndex() maps code strings to their provider items. Non-Lua items expose static code sets via GetAllProvidedCodes(). ProviderCountForCode and related methods use the index, only falling back to brute-force for dynamic LuaItems.

Profiled with dotnet-trace on the Codetracker Standard Map Tracker pack. Main thread pack load time dropped from ~7.8s to sub-sampling-interval (<10ms visible in profiler).

Developer console cleanup (closes #37)

  • Filter infrastructure logs: Voice ([Voice]), NDI ([NDI]), and MCP ([MCP]) log messages are excluded from the developer console Serilog sink. These are infrastructure concerns, not relevant to pack developers. They still go to the file log and stdout.
  • Harden NDI exception handling: NdiSendContainer.OnAttachedToVisualTree and Dispose now wrap NDI native calls in try-catch so PortAudio/NDI errors are caught and logged rather than propagating to the developer console.

Test plan

  • Load Codetracker Full Tracker (Map Tracker variant) — verify all items and locations display correctly
  • Switch between packs rapidly — no stale images, no crashes
  • Enable voice recognition after pack load — verify commands still work
  • Save/load tracker state — verify persistable references still resolve correctly
  • Open developer console — verify no Voice/NDI/MCP errors appear
  • Build succeeds in both Debug and Release with no warnings

🤖 Generated with Claude Code

…nd building

Pack load for Codetracker Map Tracker was taking ~7.8s. Three optimizations:

1. Dictionary index for GetPersistableLocationReference/ItemReference:
   Replace O(n) List.IndexOf with O(1) dictionary lookup. LocationDatabase
   and ItemDatabase now maintain a Dictionary<T, int> populated on insert.
   Saves ~2.9s from 583 location lookups during voice command building.

2. Defer BuildCommandMap to background thread: Voice recognition command
   map building (~5s) now runs on Task.Run with snapshots of item/location
   data. Atomic swap under lock ensures thread safety. Cancellable on
   pack switch. Completely removes voice recognition from the critical path.

3. Code-to-provider index in ItemDatabase: New BuildCodeIndex() creates a
   Dictionary<string, List<ITrackableItem>> mapping codes to their providers.
   LuaItems (dynamic Lua callbacks) fall back to brute-force iteration.
   All item types implement GetAllProvidedCodes() to expose their static
   code sets. ProviderCountForCode and related methods use the index when
   available, avoiding iteration over all items for each code query.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@emosaru
emosaru requested a review from a team April 13, 2026 07:34
… exception handling

The developer console (ScriptManager) is intended for pack developers to
debug their Lua scripts and pack definitions. Infrastructure subsystem
messages from Voice Recognition, NDI, and MCP were leaking into it via
the Serilog DeveloperConsoleSink, confusing users with errors unrelated
to their packs (e.g. PortAudio enumeration failures, NDI init warnings).

Changes:
- DeveloperConsoleSink now filters out log messages prefixed with
  [Voice], [NDI], or [MCP]. These still go to the file log and stdout.
- NdiSendContainer.OnAttachedToVisualTree wrapped in try-catch so NDI
  init/runtime errors are caught and logged rather than propagating.
- NdiSendContainer.Dispose NDI cleanup wrapped in try-catch to prevent
  exceptions during teardown from surfacing.

Closes #37

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@emosaru
emosaru merged commit 573b30e into avalonia Apr 13, 2026
3 checks passed
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.

1 participant