Skip to main content

Performance Tuning and Optimization

QuickJS is designed to be small and efficient. This guide covers techniques to optimize performance for your specific use case.

Build Options

Compiler Optimizations

From CMakeLists.txt, QuickJS supports various build configurations:
Release builds use -O2 or -O3 optimizations and strip debug symbols.

Disable Parser

For embedded systems where code is pre-compiled, disable the parser:
This significantly reduces binary size but requires all code to be compiled to bytecode using qjsc.

Static Builds

Create standalone executables with no runtime dependencies:

Sanitizers (Development Only)

Enable sanitizers to catch bugs that may affect performance:
Never use sanitizers in production - they significantly reduce performance.

Memory Optimization

Tune GC Threshold

Balance memory usage vs. GC frequency:
Profile your application to find the optimal threshold.

Set Memory Limits

Prevent memory bloat:

Minimize Context Count

Each context has overhead. Share contexts when possible:

Use Bytecode Compilation

Pre-compile scripts to bytecode:
Load bytecode instead of source:
Signatures:

Execution Optimization

Stack Size Configuration

Adjust stack size based on your recursion needs:
Default is JS_DEFAULT_STACK_SIZE (1 MB).

Minimize JSValue Conversions

Conversions between C and JavaScript types have overhead:

Avoid Unnecessary Exception Checks

Exception checks have minimal overhead, but can add up:

Function Call Optimization

Direct C Function Calls

Use C functions instead of JavaScript for performance-critical code:

Function Magic Numbers

Use magic numbers to create specialized versions:

ArrayBuffer and Typed Arrays

Zero-Copy Buffers

Share memory between C and JavaScript:
Signature:

Direct Buffer Access

Access buffers without copying:
Signature:

Interrupt Handler

Timeout Implementation

Signature:
The interrupt handler is called periodically during execution. Keep it fast!

Module Loading

Optimize Module Resolution

Cache module loading to avoid repeated file I/O:

Profiling

Enable Bytecode Dumps

Dump flags:

Measure Execution Time

JavaScript-Level Optimizations

While this guide focuses on C API, remember these JavaScript best practices:
  1. Avoid eval() and new Function() - they prevent JIT optimization
  2. Use typed arrays for numeric data instead of regular arrays
  3. Minimize property access in tight loops
  4. Prefer const and let over var
  5. Use strict mode ("use strict")

Benchmarking

Example benchmark harness:

Next Steps