Skip to content

perf: optimize array operations, string formatting, and property access patterns#279

Open
nev21 wants to merge 1 commit intomainfrom
nev21/perf
Open

perf: optimize array operations, string formatting, and property access patterns#279
nev21 wants to merge 1 commit intomainfrom
nev21/perf

Conversation

@nev21
Copy link
Contributor

@nev21 nev21 commented Feb 17, 2026

This commit significantly improves performance across the codebase by addressing several performance anti-patterns identified in the analysis, and adds comprehensive test coverage for equality comparisons and formatters.

Performance Optimizations:

  • Replace O(n²) splice operations with O(n) boolean array tracking in members.ts
    Functions: _hasSameMembers, _hasSameDeepMembers, includeMembersFunc,
    includeDeepMembersFunc
  • Eliminate shift() usage in assertClass.ts by replacing with index-based array access
    and arrSlice for argument handling
  • Replace string concatenation with array.join() pattern in assertionError.ts
    for error message building (lines 228-240, 307, 337)
  • Replace string concatenation with array.join() in nested.ts for escape character
    handling and add length caching
  • Add deduplication logic in equal.ts _getObjKeys using hash map for O(1) lookups
  • Cache array.length and string.length values to avoid repeated property access
    in members.ts, nested.ts, scopeContext.ts

Configuration Improvements:

  • Move maxFormatDepth from IConfig to IFormatterOptions for better organization
  • Add maxProps option to IFormatterOptions to control formatting output size
    (default: 8 items/properties)
  • Update defaultConfig.ts with new format options

Test Coverage Improvements:

  • Add comprehensive defaultFormatters.test.ts (370+ lines) covering:

    • Symbol, Date, Set, Map, Error, Function, RegExp formatters
    • Edge cases: maxProps truncation, iteration errors, property access failures
    • Objects with custom toString, prototype chains, Symbol properties
    • Primitive fallback formatting
    • Coverage increased from ~10% to 90.85% (statements)
  • Add extensive deepEqual.test.ts (560+ lines) covering:

    • Deep comparison of nested Maps, Sets, and complex structures
    • Circular reference handling (simple, nested, multiple paths)
    • Custom equals methods and valueOf comparisons
    • Symbol properties and Symbol.iterator objects
    • Typed Arrays (Uint8Array, Int16Array, Float32Array)
    • ArrayBuffer and Buffer comparison
    • Error objects, RegExp, Promises, Functions
    • WeakMap, WeakSet, and sparse arrays
    • Array-like objects and mixed key types
    • Coverage increased from ~45% to 89.03% (statements) for equal.ts

@nev21 nev21 added this to the 0.1.8 milestone Feb 17, 2026
Copilot AI review requested due to automatic review settings February 17, 2026 05:42
@nev21 nev21 requested review from a team as code owners February 17, 2026 05:42
@nev21 nev21 enabled auto-merge (squash) February 17, 2026 05:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements comprehensive performance optimizations across the tripwire codebase, focusing on reducing algorithmic complexity and eliminating redundant operations. The changes move the maxFormatDepth configuration from IConfig to IFormatterOptions for better organization, add a new maxProps option to limit formatting output size, and optimize several key areas including array operations, string formatting, and property access patterns.

Changes:

  • Replaces O(n²) splice operations with O(n) boolean array tracking in members comparison functions
  • Eliminates shift() usage in favor of index-based array access in stack trace capture
  • Replaces string concatenation with array.join() pattern in all formatters (arrays, objects, sets, maps)
  • Adds deduplication logic using hash maps for O(1) lookups in key collection
  • Caches array/string length values to avoid repeated property access in hot loops
  • Refactors configuration by moving maxFormatDepth to IFormatterOptions and adding maxProps option (default: 8)

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
core/src/interface/IFormatterOptions.ts Added maxProps and maxFormatDepth properties to IFormatterOptions with documentation
core/src/interface/IConfig.ts Removed maxFormatDepth property (moved to IFormatterOptions)
core/src/config/defaultConfig.ts Updated default config to include maxProps: 8 and maxFormatDepth: 50 in format object
core/src/internal/_formatValue.ts Updated to access maxFormatDepth from cfg.format.maxFormatDepth with fallback
core/src/internal/_defaultFormatters.ts Replaced string concatenation with array.join() pattern, added maxProps limiting, improved constructor formatter, added Date formatter, optimized _getObjKeys with hash map deduplication
core/src/assert/assertionError.ts Replaced shift() with index-based array access in _captureStackTrace
core/src/internal/parseStack.ts Cached lines.length for performance
core/src/assert/scopeContext.ts Cached token.length for performance
core/src/assert/funcs/nested.ts Cached tokens.length for performance
core/src/assert/funcs/members.ts Replaced O(n²) splice operations with O(n) boolean array tracking in all member comparison functions, cached array lengths
core/src/assert/funcs/equal.ts Added hash map deduplication in _getObjKeys for O(1) lookups
core/test/src/config/maxDepth.test.ts Updated tests to use assertConfig.format.maxFormatDepth and $ops.reset()
core/test/src/assert/deepEqual.edgeCases.test.ts Updated to use assertConfig.$ops.reset()
core/test/src/assert/assert.property.test.ts Updated expected output to match new formatter behavior
core/test/src/assert/assert.format.test.ts Updated to use assertConfig.$ops.reset() consistently
core/test/src/assert/adapters/notAdapter.test.ts Updated to use assertConfig.$ops.reset()
core/test/src/assert/adapters/exprAdapter.test.ts Updated to use assertConfig.$ops.reset()
shim/chai/test/src/chaiAssert.test.ts Updated expected error messages to match new formatter output showing property values

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

❌ Patch coverage is 89.83051% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.87%. Comparing base (2e6e189) to head (007f6f9).

Files with missing lines Patch % Lines
core/src/internal/_defaultFormatters.ts 81.92% 15 Missing ⚠️
core/src/assert/funcs/equal.ts 85.71% 2 Missing ⚠️
core/src/assert/assertionError.ts 90.90% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #279      +/-   ##
==========================================
+ Coverage   92.79%   92.87%   +0.08%     
==========================================
  Files          78       78              
  Lines        3454     3564     +110     
  Branches      885      904      +19     
==========================================
+ Hits         3205     3310     +105     
- Misses        249      254       +5     
Files with missing lines Coverage Δ
core/src/assert/assertClass.ts 93.80% <100.00%> (ø)
core/src/assert/funcs/members.ts 98.91% <100.00%> (+0.11%) ⬆️
core/src/assert/funcs/nested.ts 91.11% <100.00%> (+0.78%) ⬆️
core/src/assert/scopeContext.ts 90.69% <100.00%> (+0.03%) ⬆️
core/src/config/defaultConfig.ts 100.00% <ø> (ø)
core/src/internal/_formatValue.ts 90.62% <100.00%> (+3.32%) ⬆️
core/src/internal/parseStack.ts 98.27% <100.00%> (+0.01%) ⬆️
core/src/assert/assertionError.ts 88.05% <90.90%> (+0.22%) ⬆️
core/src/assert/funcs/equal.ts 88.11% <85.71%> (+0.13%) ⬆️
core/src/internal/_defaultFormatters.ts 91.08% <81.92%> (-2.75%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nev21 nev21 disabled auto-merge February 17, 2026 06:27
nevware21-bot
nevware21-bot previously approved these changes Feb 17, 2026
Copy link
Contributor

@nevware21-bot nevware21-bot left a comment

Choose a reason for hiding this comment

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

Approved by nevware21-bot

…ss patterns

This commit significantly improves performance across the codebase by addressing several performance anti-patterns identified in the analysis, and adds comprehensive test coverage for equality comparisons and formatters.

Performance Optimizations:
- Replace O(n²) splice operations with O(n) boolean array tracking in members.ts
  Functions: _hasSameMembers, _hasSameDeepMembers, includeMembersFunc,
  includeDeepMembersFunc
- Eliminate shift() usage in assertClass.ts by replacing with index-based array access
  and arrSlice for argument handling
- Replace string concatenation with array.join() pattern in assertionError.ts
  for error message building (lines 228-240, 307, 337)
- Replace string concatenation with array.join() in nested.ts for escape character
  handling and add length caching
- Add deduplication logic in equal.ts _getObjKeys using hash map for O(1) lookups
- Cache array.length and string.length values to avoid repeated property access
  in members.ts, nested.ts, scopeContext.ts

Configuration Improvements:
- Move maxFormatDepth from IConfig to IFormatterOptions for better organization
- Add maxProps option to IFormatterOptions to control formatting output size
  (default: 8 items/properties)
- Update defaultConfig.ts with new format options

Test Coverage Improvements:
- Add comprehensive defaultFormatters.test.ts (370+ lines) covering:
  * Symbol, Date, Set, Map, Error, Function, RegExp formatters
  * Edge cases: maxProps truncation, iteration errors, property access failures
  * Objects with custom toString, prototype chains, Symbol properties
  * Primitive fallback formatting
  * Coverage increased from ~10% to 90.85% (statements)

- Add extensive deepEqual.test.ts (560+ lines) covering:
  * Deep comparison of nested Maps, Sets, and complex structures
  * Circular reference handling (simple, nested, multiple paths)
  * Custom equals methods and valueOf comparisons
  * Symbol properties and Symbol.iterator objects
  * Typed Arrays (Uint8Array, Int16Array, Float32Array)
  * ArrayBuffer and Buffer comparison
  * Error objects, RegExp, Promises, Functions
  * WeakMap, WeakSet, and sparse arrays
  * Array-like objects and mixed key types
  * Coverage increased from ~45% to 89.03% (statements) for equal.ts
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 5 comments.

let theValue = "{";
let parts: string[] = [];
let idx = 0;
let maxProps = ctx.cfg.format.maxProps;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

Potential runtime error: Same as line 29 - direct access to ctx.cfg.format.maxProps without checking if ctx.cfg.format exists. Use safe accessor: (ctx.cfg.format && ctx.cfg.format.maxProps) || 8.

Suggested change
let maxProps = ctx.cfg.format.maxProps;
let maxProps = (ctx.cfg.format && ctx.cfg.format.maxProps) || 8;

Copilot uses AI. Check for mistakes.
let first = true;
let parts: string[] = [];
let idx = 0;
let maxProps = ctx.cfg.format.maxProps;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

Potential runtime error: Same as line 29 - direct access to ctx.cfg.format.maxProps without checking if ctx.cfg.format exists. Use safe accessor: (ctx.cfg.format && ctx.cfg.format.maxProps) || 8.

Copilot uses AI. Check for mistakes.
@nev21 nev21 enabled auto-merge (squash) February 17, 2026 07:26
@nev21 nev21 requested a review from nevware21-bot February 17, 2026 07:26
Copy link
Contributor

@nevware21-bot nevware21-bot left a comment

Choose a reason for hiding this comment

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

Approved by nevware21-bot

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