Skip to content

Decode Dialog/Talk ExcelConfigData partially via msgspec Structs#388

Merged
isundaylee merged 2 commits into
mainfrom
regen-precompute-speedup
Jul 11, 2026
Merged

Decode Dialog/Talk ExcelConfigData partially via msgspec Structs#388
isundaylee merged 2 commits into
mainfrom
regen-precompute-speedup

Conversation

@isundaylee

@isundaylee isundaylee commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What & why

Profiling the post-msgspec 17s CHS regen showed the largest chunks of the precompute region were full decodes of huge Excel files from which only a handful of fields are ever consumed. This switches the two biggest — DialogExcelConfigData.json (93MB) and TalkExcelConfigData_*.json (141MB) — to partial typed decodes: their item types are now msgspec.Structs with only the consumed fields, decoded directly with msgspec.json.decode(..., type=...). msgspec skips unparsed fields, so:

  • Dialog chain (critical path of precompute_for_workers, ~3.9s): full decode + deobfuscation rename + mapping passes drop from ~3.8s to ~0.4s (~10x).
  • Talk excel (on the build_talk_tracker critical path): decode drops from ~1.0s to ~0.2s.

Full CHS regen: 17.2s → 13.1s.

Notable details

  • The rotating obfuscated dialog-id key (GFLDJMJKIKE) is now a public DIALOG_EXCEL_ID_KEY constant in deobfuscation.py, used both in the field-mapping literal and as the dialog Struct's rename target — one source of truth. If the key rotates in a future build and the constant goes stale, the decode fails loudly with a missing-required-field error.
  • deobfuscate_dialog_excel_config_data is deleted (the Struct rename replaces it), along with the unused talkRole field and its DialogTalkRole TypedDict (no other references).
  • The talk Structs stay strict for the current build only. first_seen.scan_snapshot scans historical AGD checkouts where the id key style varies by era (id/Id/_id), so it now goes through the same load_excel_raw + _row_id path it already uses for every other excel domain; the split-vs-legacy-single-file discovery is extracted into DataRepo.talk_excel_file_names() shared by both paths.
  • agd_types now imports msgspec and deobfuscation; both are cycle-free.

Testing

  • Isolated benchmarks: partial decodes produce values identical to the old paths (203,908 dialog entries; 42,001 talk entries on all 4 fields).
  • Full CHS regen output is byte-identical to a pre-change baseline (diff -r, excluding metadata.json commit fields).
  • first_seen.scan_snapshot smoke-tested against the current build (talk domain: 42,001 ids, matching the typed decode).
  • pre-commit run (black, isort, mypy) and the full pytest suite pass (199 passed, 57 skipped).

🤖 Generated with Claude Code

isundaylee and others added 2 commits July 11, 2026 08:06
- DialogExcelConfigDataItem is now a msgspec.Struct with only the consumed
  fields; the rotating obfuscated dialog-id key is a shared constant in
  deobfuscation.py
- Cuts the dialog-hash precompute chain from ~3.8s to ~0.4s (CHS regen
  17.2s -> 14.3s), with byte-identical corpus output

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- TalkExcelConfigDataItem is now a msgspec.Struct with only the consumed
  cleartext fields; consumers use attribute access
- talk excel file discovery (split vs legacy single file) extracted into
  talk_excel_file_names(); first_seen.scan_snapshot uses it with
  load_excel_raw + _row_id so historic-era key styles keep working

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@isundaylee isundaylee changed the title Decode DialogExcelConfigData partially via a msgspec Struct Decode Dialog/Talk ExcelConfigData partially via msgspec Structs Jul 11, 2026
@isundaylee isundaylee merged commit 83718fd into main Jul 11, 2026
@isundaylee isundaylee deleted the regen-precompute-speedup branch July 11, 2026 08:18
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