Skip to content

perf(request): optimize hot-path transformations and add runtime benchmark harness#17

Closed
ndycode wants to merge 3 commits into
mainfrom
audit/perf-runtime-path-2026-03-01
Closed

perf(request): optimize hot-path transformations and add runtime benchmark harness#17
ndycode wants to merge 3 commits into
mainfrom
audit/perf-runtime-path-2026-03-01

Conversation

@ndycode
Copy link
Copy Markdown
Owner

@ndycode ndycode commented Feb 28, 2026

Summary

  • Optimize request-path hot functions with behavior parity:
    • ilterInput now uses a single pass for filtering/ID stripping and safely skips sparse entries.
    • cleanupToolDefinitions now clones and cleans only parameter schema trees instead of deep-cloning whole tool objects.
  • Add reusable runtime performance harness:
    • scripts/benchmark-runtime-path.mjs

pm run bench:runtime-path

pm run bench:runtime-path:quick

  • Architect-blocker follow-up:
    • Added sparse-array regression guard + test coverage for ilterInput.

Performance Evidence

Baseline and after measurements (same local micro-benchmark shape, Node v25.6.1):

Benchmark Before avg ms After avg ms Delta
ilterInput_1200 0.0821 0.0789 -3.9%
cleanupToolDefinitions_140x25 2.7475 2.2972 -16.4%
�ccountHybridLoop_200x200 0.1676 0.1003 -40.2%

Current reusable harness output (
ode scripts/benchmark-runtime-path.mjs --iterations=60):

  • ilterInput_small: 0.0259 ms
  • ilterInput_large: 0.1165 ms
  • cleanupToolDefinitions_medium: 0.3081 ms
  • cleanupToolDefinitions_large: 2.3519 ms
  • �ccountHybridSelection_200: 0.0739 ms

Validation

pm run typecheck ✅

pm run build ✅

  • Targeted regression suites ✅

px vitest run test/request-transformer.test.ts test/property/transformer.property.test.ts

pm test ⚠️ 1 known pre-existing failure on main:

  • est/documentation.test.ts > uses scoped package only in explicit legacy migration notes
    

Risk/Compatibility

  • No public API changes.
  • Behavior parity preserved for transformed inputs; sparse-array safety now explicitly covered.

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

reduced request-path allocation overhead by optimizing filterInput (single-pass iteration) and cleanupToolDefinitions (selective cloning). added sparse array guard to prevent crashes on malformed inputs with regression test coverage.

  • filterInput now uses for-loop instead of filter/map chains, guards against sparse/null entries
  • cleanupToolDefinitions shallow-spreads tool objects, only deep-clones mutated parameters schema
  • new runtime benchmark harness validates performance improvements
  • sparse array regression test added (line 384-394 in request-transformer.test.ts)

windows filesystem/token safety: not applicable - no file i/o or credential handling in hot-path changes. benchmark script only writes json output with standard mkdir/writeFile, no cleanup operations requiring retry logic.

vitest coverage: existing tool-utils tests already cover undefined property cleanup (lines 272-309), property-based tests verify filterInput behavior parity.

Confidence Score: 5/5

  • safe to merge - performance optimization with behavior parity and comprehensive test coverage
  • all changes are pure function optimizations with existing test coverage. sparse array guard prevents crashes. no concurrency, filesystem, or token safety risks. benchmark harness enables ongoing performance validation.
  • no files require special attention

Important Files Changed

Filename Overview
lib/request/request-transformer.ts optimized filterInput from filter/map chains to single-pass for loop, added sparse array guard to prevent crashes on malformed inputs
lib/request/helpers/tool-utils.ts optimized cleanupToolDefinitions to use shallow spread + selective deep clone instead of full deep clone, added undefined property cleanup to maintain behavior parity
test/request-transformer.test.ts added sparse array regression test covering the filterInput guard, indentation fix for existing test
scripts/benchmark-runtime-path.mjs new reusable runtime benchmark harness for hot-path functions, measures filterInput, cleanupToolDefinitions, and account selection performance
package.json added bench:runtime-path and bench:runtime-path:quick scripts for runtime performance testing

Last reviewed commit: 9cd71c4

ndycode and others added 2 commits March 1, 2026 07:09
Avoid extra array passes in filterInput and clone only tool schema trees during cleanupToolDefinitions, preserving behavior while reducing hot-path work.

Co-authored-by: Codex <noreply@openai.com>
Add a reusable benchmark script and npm commands to measure request-path hotspots (filterInput, cleanupToolDefinitions, and account selection) for before/after performance tracking.

Co-authored-by: Codex <noreply@openai.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 28, 2026

Warning

Rate limit exceeded

@ndycode has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 59 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 36cf5d4 and 9cd71c4.

📒 Files selected for processing (5)
  • lib/request/helpers/tool-utils.ts
  • lib/request/request-transformer.ts
  • package.json
  • scripts/benchmark-runtime-path.mjs
  • test/request-transformer.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch audit/perf-runtime-path-2026-03-01

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

Prevent sparse-array holes from causing runtime errors in the single-pass filterInput loop and add regression coverage for sparse entries.

Co-authored-by: Codex <noreply@openai.com>
@ndycode ndycode marked this pull request as ready for review February 28, 2026 23:26
@ndycode
Copy link
Copy Markdown
Owner Author

ndycode commented Feb 28, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

ndycode added a commit that referenced this pull request Mar 1, 2026
Source-PR: #17
Source-Branch: audit/perf-runtime-path-2026-03-01
Source-Head: 9cd71c4

Co-authored-by: Codex <noreply@openai.com>
@ndycode
Copy link
Copy Markdown
Owner Author

ndycode commented Mar 1, 2026

Fixed items

  1. Superseded by PR supersede: unify PRs #15 #16 #17 #18 #19 #20 #24 #25 into one branch #27 ( eat/unified-supersede-all-prs), which consolidates PR perf(request): optimize hot-path transformations and add runtime benchmark harness #17 ($branch) into the single canonical review branch.

Deferred items

  • None.

Blocked items

  • None.

Validation evidence

pm run clean:repo:check - pass

pm run audit:ci - pass

pm run typecheck - pass

pm run lint - pass

pm run build - pass

pm test - pass (92 files, 2113 tests)

@ndycode ndycode closed this Mar 1, 2026
ndycode added a commit that referenced this pull request Mar 3, 2026
@ndycode ndycode deleted the audit/perf-runtime-path-2026-03-01 branch March 3, 2026 12:12
ndycode added a commit that referenced this pull request Apr 6, 2026
Source-PR: #17
Source-Branch: audit/perf-runtime-path-2026-03-01
Source-Head: 9cd71c4

Co-authored-by: Codex <noreply@openai.com>
ndycode added a commit that referenced this pull request Apr 6, 2026
ndycode added a commit that referenced this pull request Jun 2, 2026
Completes partial fixes flagged in the third review, bumps to v2.2.1.

Real bugs (prior fixes were incomplete):
- request/fetch-helpers: isUnsupportedCodexModelForChatGpt (the handleErrorResponse
  path) now also matches NORMALIZED_UNSUPPORTED_MODEL_PATTERN, so a 400 'model not
  currently available for this chatgpt account' gets the entitlement rewrite, not
  generic error guidance (#13)
- forecast: quota-exhausted accounts are classified 'delayed' (not 'unavailable'),
  so they slipped the recommendation filter; added an explicit exhausted flag and
  excluded it, returning null when the whole pool is exhausted (#10)
- storage/record-utils: clampIndex guards NaN -> 0 (Math.trunc(NaN) propagated) (#16)
- local-client-tokens: debounce lastUsedAt persistence (60s threshold) so the
  bearer-verify hot path stops writing to disk every request; +chmod 0o700
  re-assert on the token-store dir (#12, #11)
- mcodex: relay SIGTERM/SIGINT to the spawned child so it isn't orphaned (#15)

Test quality:
- local-client-tokens: parameterized rename-retry test over ENOTEMPTY/EAGAIN/EACCES (#18)
- storage-flagged: clear the H4 deadlock-guard timer on the happy path (#17)
- storage: removeWithRetry for suite cleanup (#19)

Release:
- bump package.json + .codex-plugin/plugin.json to 2.2.1
- add docs/releases/v2.2.1.md; point docs portal + README at it

Known follow-ups (documented, deferred — need design, not rushed into a patch):
config env-path save is a single-process CAS not a true cross-process lock (#8/#9);
verifyLocalClientBearerToken read stays serialized but a fuller lease is future work;
runtime proxy routingMutex='enabled' still has a select/commit cursor race (#14)
requiring an async refactor of chooseAccount across its call sites.

Full suite: 4337 passed, 3 skipped, 0 failed; typecheck + lint clean.
ndycode added a commit that referenced this pull request Jun 2, 2026
Real bug introduced by the round-3 config lock (#18):
- the cross-process config lock fixed expiresAt once and never renewed, and
  released by unconditionally unlinking the lockfile. A save running longer than
  CONFIG_LOCK_TTL_MS could be deemed stale and stolen by another process, after
  which the original holder would delete the NEW owner's lock and reopen
  concurrent saves. Added a per-acquisition owner token (randomUUID) to the lock
  payload and a releaseConfigLockIfOwner() that compares-before-unlink, so a
  holder never deletes a lock it no longer owns. Regressions: stale-foreign-lock
  takeover (cleans only its own lock) + live-foreign-lock respected (times out,
  foreign lock untouched, no partial apply).

Nits:
- mcodex-launcher test: dropped the explicit vitest globals import (#17).
- runtime-rotation-proxy: replaced the stale 'KNOWN GAP (L4)' comment on
  chooseAccount with accurate docs — the race is closed via the reentrant
  withRoutingMutex on the hot path (#19).

Full suite: 4343 passed, 3 skipped, 0 failed; typecheck + lint clean.
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