perf: optimize array operations, string formatting, and property access patterns#279
perf: optimize array operations, string formatting, and property access patterns#279
Conversation
There was a problem hiding this comment.
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 Report❌ Patch coverage is
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
🚀 New features to boost your workflow:
|
nevware21-bot
left a comment
There was a problem hiding this comment.
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
| let theValue = "{"; | ||
| let parts: string[] = []; | ||
| let idx = 0; | ||
| let maxProps = ctx.cfg.format.maxProps; |
There was a problem hiding this comment.
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.
| let maxProps = ctx.cfg.format.maxProps; | |
| let maxProps = (ctx.cfg.format && ctx.cfg.format.maxProps) || 8; |
| let first = true; | ||
| let parts: string[] = []; | ||
| let idx = 0; | ||
| let maxProps = ctx.cfg.format.maxProps; |
There was a problem hiding this comment.
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.
nevware21-bot
left a comment
There was a problem hiding this comment.
Approved by nevware21-bot
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:
Functions: _hasSameMembers, _hasSameDeepMembers, includeMembersFunc,
includeDeepMembersFunc
and arrSlice for argument handling
for error message building (lines 228-240, 307, 337)
handling and add length caching
in members.ts, nested.ts, scopeContext.ts
Configuration Improvements:
(default: 8 items/properties)
Test Coverage Improvements:
Add comprehensive defaultFormatters.test.ts (370+ lines) covering:
Add extensive deepEqual.test.ts (560+ lines) covering: