Skip to content

perf(cli): avoid cloning JSON results into an intermediate tree - #274

Merged
jlucaso1 merged 2 commits into
mainfrom
perf/cli-json-borrowed-envelope
Oct 29, 2026
Merged

jlucaso1 merged 2 commits into
mainfrom
perf/cli-json-borrowed-envelope

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

CLI JSON results currently clone the entire payload into serde_json::Value before pretty-printing it. Serialize a borrowed success envelope directly. Preserve the parsed JSON, pretty formatting and null fallback on serialization failure. Object key order follows the serializer; the previous intermediate map's ordering also varied with serde_json/preserve_order. The CLI documents keys and values, not key order.

Release comparison on one Linux runner without serde_json/preserve_order for the first table, base algorithm copied verbatim from e6e3020 versus the production helper. Two independent runs, 12 alternating paired samples per scenario, 10 serializations per timing sample. Allocation accounting runs separately with counters disabled during timing. Synthetic MessageDto inputs include UTF-8 and escaped characters.

Messages / text bytes Median formatting time base → head, run 1 Paired median reduction, runs 1 / 2 Additional peak requested live heap base → head Allocation/reallocation calls base → head
1 / 100 3.37 → 0.80 µs 76.3% / 74.1% 6,218 → 1,024 B 51 → 4
200 / 100 0.726 → 0.134 ms 81.4% / 81.5% 1,043,490 → 131,072 B 8,416 → 11
5,000 / 100 25.70 → 3.24 ms 87.2% / 87.4% 27,002,722 → 4,194,304 B 210,021 → 16
200 / 16,000 8.09 → 7.27 ms 10.1% / 7.7% 15,661,026 → 8,388,608 B 8,422 → 17

The same release comparison was repeated twice with --features serde_json/preserve_order, matching workspace feature unification. The production serializer is identical; only the legacy intermediate map implementation changes.

Messages / text bytes Median base → head, first run Paired median reduction, runs 1 / 2 Additional peak requested heap base → head Allocation/reallocation calls base → head
1 / 100 3.46 → 0.88 µs 74.8% / 76.2% 4,862 → 1,024 B 50 → 4
200 / 100 0.778 → 0.122 ms 84.3% / 84.3% 825,622 → 131,072 B 8,017 → 11
5,000 / 100 22.25 → 3.12 ms 86.1% / 86.0% 21,562,454 → 4,194,304 B 200,022 → 16
200 / 16,000 7.39 → 6.49 ms 11.8% / 11.7% 15,443,158 → 8,388,608 B 8,023 → 17

This measures formatting only. It excludes DTO construction, IPC, stdout, process startup and the connected daemon. The input DTO is excluded from additional heap. Requested heap is not RSS; CPU time and RSS were not measured. A test allocator wrapper remains installed during timing, with accounting disabled. Long text remains dominated by escaping and output allocation. The final output String still exists.

Validated cargo test -p oxidezap-cli --all-features both with and without --features serde_json/preserve_order, scoped all-target Clippy with -D warnings including preserve_order, formatting and diff checks. The original two byte-comparison assertions failed under workspace feature unification; the follow-up commit compares parsed values and explicitly checks ok=true and data=null. The production serializer is unchanged by that follow-up. Regression tests compare parsed JSON including empty payloads/escaping/nulls, and check the existing serialization-error fallback.

Reproduce: cargo test -p oxidezap-cli --release --test json_cost -- --ignored --nocapture.

Only CLI output and its isolated test changed. No DTO/protocol, daemon, SQL, account selection, read-only, manifests, lockfiles or #265 changes. No new dependencies.


Summary by cubic

CLI JSON output now serializes a borrowed success envelope directly instead of cloning the entire payload into an intermediate serde_json::Value, cutting formatting time by up to ~87% and reducing allocations by orders of magnitude.

  • Object key order follows the serializer; parsed JSON is verified with and without preserve_order.
  • The null fallback on serialization failure is preserved; object key ordering is not a CLI contract.
  • Adds a regression and performance benchmark test in json_cost.rs covering timing, allocation counts, and parsed JSON equality (empty payloads, escaping, nulls, and the failure fallback).

Written for commit 4ca5453. Summary will update on new commits.

View guided diff Turn on auto-fix

Copy link
Copy Markdown
Member Author

@codex review

Please review the borrowed JSON success envelope and the separate release comparison. Check parsed JSON compatibility, null fallback, declared key ordering, and the allocation test's safety and measurement limits.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 33 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 972634d6-b492-49e4-a0c4-807e2f90c973
Commits

Reviewing files that changed from the base of the PR and between e6e3020 and 4ca5453.

Files selected for processing: 2
  • crates/cli/src/output.rs
  • crates/cli/tests/json_cost.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T23:08:05.811427Z 4ca5453 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 4a13dfb6ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

jlucaso1 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member Author

Compatibility audit, updated after the workspace feature-unification failure:

  • borrowed_envelope_preserves_json_values parses old and new output into serde_json::Value and compares empty/populated MessageDto lists and nested arrays/null/numbers. The text fixture includes UTF-8 é, newline, quote and backslash.
  • failed_serialization_keeps_the_null_fallback uses a failing Serialize implementation, compares parsed old/new envelopes and explicitly asserts ok=true/data=null.
  • Existing consumer error tests parse stderr and verify codes/nonzero exit. The export consumer parses actual CLI stdout and reads .data. Account selection and read-only tests remain covered.
  • docs/cli.md promises the envelope, streams and exit codes, with no key-order contract. A search of docs and consumer tests found no alphabetical/sorted key-order requirement. Envelope and DTO key ordering can change; parsed JSON is preserved.
  • The original map/fallback tests incorrectly compared bytes. With workspace-unified serde_json/preserve_order, the old envelope emits ok/data instead of data/ok. This caused the initial Linux CI failure. Both failures were reproduced locally, then corrected in 4ca5453.
  • The full CLI suite passes locally with and without --features serde_json/preserve_order; scoped all-target Clippy also passes with that feature. Codex and CI have been requested on the updated head. The production serializer has not changed since the original measurements.

Copy link
Copy Markdown
Member Author

@codex review

The follow-up commit fixes regression-test comparisons for workspace-unified serde_json/preserve_order. The production serializer is unchanged. I reproduced both previous test failures locally with --features serde_json/preserve_order, then confirmed the full CLI suite passes both with and without that feature, plus scoped Clippy. Please review the final head and the JSON value/null-fallback assertions. Key ordering is not part of the CLI contract.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 4ca54539e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jlucaso1
jlucaso1 merged commit cbacb4e into main Oct 29, 2026
14 checks passed
@jlucaso1
jlucaso1 deleted the perf/cli-json-borrowed-envelope branch October 29, 2026 23:45
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