Skip to content

perf: add JSON sidecar for data model loading (~100x faster) - #898

Closed
ChristopherJHart wants to merge 1 commit into
netascode:mainfrom
ChristopherJHart:fix/perf-json-sidecar
Closed

perf: add JSON sidecar for data model loading (~100x faster)#898
ChristopherJHart wants to merge 1 commit into
netascode:mainfrom
ChristopherJHart:fix/perf-json-sidecar

Conversation

@ChristopherJHart

Copy link
Copy Markdown
Contributor

Summary

Adds a JSON sidecar cache for the merged data model, eliminating repeated YAML parsing across test subprocesses.

Problem

Every test subprocess re-parses the merged data model YAML file using ruamel's pure-Python parser (YAML(typ="safe", pure=True)). On a 2.3 MB file, this takes 1.9 seconds per test. For a 169-test device, that's 322 seconds (48% of total setup time) spent re-parsing the same unchanging file.

Solution

  • The orchestrator writes a .cache.json sidecar alongside the YAML at merge time
  • load_data_model() prefers the JSON sidecar when present and fresh (mtime check)
  • Falls back to YAML if sidecar is missing/stale, and writes the sidecar after parsing

Measured Impact

  • Per-test data model load: 1.9s → 0.017s (112x improvement)
  • Single device (169 tests): eliminates ~322s of redundant parsing
  • Fleet (7 devices): measured 25 min → 2 min 42s (combined with other fixes)

Files Changed

File Change
nac_test/data_merger.py Write JSON sidecar after YAML
nac_test/pyats_core/common/base_test.py Prefer JSON sidecar in load_data_model()

Test plan

  • Existing tests pass (no behavioral change — same data, faster loading)
  • Validated end-to-end on 7-device NX-OS fleet (1183 tests)
  • Validated end-to-end on 2-device FTD HA pair (164 tests)
  • Graceful fallback when sidecar is missing or stale

🤖 Generated with Claude Code

The merged data model YAML file is re-parsed by every test subprocess using
ruamel's pure-Python parser (1.9s per test on a 2.3MB file). This adds a
JSON sidecar (.cache.json) written once by the orchestrator and read by
tests via json.load() (~0.005s).

The orchestrator writes both YAML and JSON at merge time. load_data_model()
prefers the JSON sidecar when present and fresh, falling back to YAML if
missing or stale. If a test is the first to run (no sidecar), it writes one
after parsing YAML so subsequent tests benefit.

Measured: 1.9s -> 0.017s per test (112x improvement on data model loading).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@oboehmer oboehmer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@ChristopherJHart , please check #931 (comment) for an alternative approach.. TLDR: I would just create merged_data_model_test_variables.json already in main and promote it as a first-class artifcat, with the option to deprecate the .yaml format altogether..

@oboehmer oboehmer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would actually drop the .yaml file altogether, implemented it via #933, please review and close this one if you agree.

@ChristopherJHart

Copy link
Copy Markdown
Contributor Author

Closing in favor of #933

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.

2 participants