Skip to content

perf: optimize JS tracer performance by reusing objects #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mattsse
Copy link
Contributor

@mattsse mattsse commented Jun 13, 2025

Summary

This PR addresses a significant performance bottleneck in the JavaScript tracer implementation where new JS objects were created for every EVM instruction execution. The optimization introduces an object reuse pattern that dramatically reduces allocation overhead.

Changes

Core Implementation

  • Added step_object and db_object fields to JsInspector struct for reusable objects
  • Implemented create_js_object_template() methods for one-time object structure creation
  • Added update_js_object() methods for in-place data updates without recreation
  • Modified try_step() and try_fault() methods to use lazy initialization and object reuse

Performance Optimization

  • Before: 2 new JS objects created per EVM instruction (millions per transaction trace)
  • After: 2 JS objects created once per tracer instance, then updated in-place
  • Impact: Massive reduction in heap allocations and garbage collection pressure

Test Coverage

  • Added 38 comprehensive test cases covering:
    • Unit tests for template creation and object updates
    • Integration tests for JS inspector functionality
    • Performance tests verifying no object leaks
    • Equivalence tests ensuring backward compatibility

Backward Compatibility

All existing JavaScript tracer code continues to work unchanged. The original into_js_object() methods are preserved for compatibility.

Test Results

All 46 tests pass, including 8 existing tests and 38 new tests specifically for this optimization.

Type of Change

  • Performance improvement
  • New feature (object reuse pattern)
  • Breaking change
  • New tests added

mattsse added 2 commits June 13, 2025 09:38
This change eliminates the performance bottleneck in JavaScript tracing
where new objects were created for every EVM instruction execution.

Key improvements:
- Added object reuse pattern with lazy initialization for step and database objects
- Implemented create_js_object_template() and update_js_object() methods
- Modified try_step() and try_fault() to reuse objects instead of recreating
- Reduced object allocation from millions per trace to 2 per tracer instance
- Added comprehensive test suite with 38 new tests covering unit, integration, and performance scenarios

Performance impact:
- Before: 2 new JS objects created per EVM instruction (potentially millions per transaction)
- After: 2 JS objects created once per tracer instance, then updated in-place
- Expected: Significant reduction in allocation overhead and garbage collection pressure

Backward compatibility maintained - existing JavaScript tracer code works unchanged.
- Add enter_frame_object and exit_frame_object fields to JsInspector
- Implement create_js_object_template and update_js_object for CallFrame and FrameResult
- Update try_enter and try_exit to use lazy initialization and object reuse
- Add comprehensive tests for enter/exit optimization
- This completes the object reuse pattern for all JS tracer hot paths
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