Skip to content

Performance Testing

Brenda Willams edited this page Oct 22, 2025 · 2 revisions

⚑ Performance Testing Tutorial

Master Arsenal Lab's performance testing capabilities - Learn to benchmark Bun applications, analyze bottlenecks, and optimize for maximum performance.

Beginner Friendly Time Hands-on

🎯 Tutorial Overview

This tutorial will teach you how to:

  • Run comprehensive performance benchmarks
  • Compare Bun vs Node.js performance
  • Analyze benchmark results and identify bottlenecks
  • Create custom performance tests
  • Optimize your applications based on results

πŸ“‹ Prerequisites

  • Arsenal Lab installed and running (Getting Started)
  • Basic JavaScript/TypeScript knowledge
  • 5-10 minutes of free time

πŸš€ Step 1: Launch Performance Arsenal

Start Arsenal Lab

cd Arsenal-Lab
bun run dev

Navigate to http://localhost:3655 and click "Performance Arsenal".

Interface Overview

You'll see:

  • Benchmark Tabs: Crypto, PostMessage, Registry, Memory
  • Control Panel: Run buttons and configuration options
  • Results Display: Real-time metrics and charts
  • Hardware Info: Your system's specifications

πŸ§ͺ Step 2: Run Your First Benchmark

Crypto Benchmark

  1. Click the "Crypto" tab
  2. Click "Run Benchmark"
  3. Watch the real-time progress bar
  4. View the results comparison

What you'll see:

Bun SHA-256: 2,450 ops/sec
Node SHA-256: 1,890 ops/sec
Speedup: 1.3x faster

Understanding Results

  • Operations per second: Higher is better
  • Speedup ratio: How much faster Bun is vs Node.js
  • Consistency: Look for stable performance across runs

πŸ” Step 3: Deep Performance Analysis

Memory Benchmark

  1. Switch to the "Memory" tab
  2. Click "Run Benchmark"
  3. Monitor memory usage in real-time
  4. Analyze garbage collection patterns

Key metrics to watch:

  • Heap usage: Memory allocated by your application
  • GC pauses: How often garbage collection runs
  • Memory leaks: Increasing memory usage over time

PostMessage Benchmark

  1. Click the "PostMessage" tab
  2. Adjust the "Message Size" slider (try 1KB, 10KB, 100KB)
  3. Run the benchmark for different sizes
  4. Compare throughput across message sizes

What you'll learn:

  • Message passing efficiency between threads
  • Serialization overhead for different data sizes
  • Web Worker communication patterns

πŸ“Š Step 4: Advanced Benchmarking

Registry Benchmark

  1. Switch to "Registry" tab
  2. Set "Registry Size" to 1000
  3. Click "Run Benchmark"
  4. Experiment with different registry sizes

Registry operations tested:

  • Registration: Adding items to a registry
  • Lookup: Finding items by key
  • Iteration: Processing all items
  • Deletion: Removing items

Custom Iterations

Try running each benchmark with different iteration counts:

  • 100 iterations: Quick feedback
  • 1,000 iterations: Balanced testing
  • 10,000 iterations: Performance characterization

🧠 Step 5: Interpreting Results

Performance Patterns

Consistent Results

βœ… Good: Bun consistently 1.2-1.5x faster
βœ… Good: Memory usage stable at ~50MB
βœ… Good: Low GC pause frequency

Problematic Results

❌ Bad: Inconsistent performance across runs
❌ Bad: Memory usage growing over time
❌ Bad: High GC pause frequency (>100ms)

Hardware Impact

CPU-bound tasks (Crypto, Registry):

  • More cores = Better performance
  • Clock speed heavily influences results

Memory-bound tasks (Memory benchmark):

  • RAM amount affects maximum working set
  • Memory bandwidth impacts throughput

I/O-bound tasks (PostMessage):

  • Inter-core communication speed matters
  • System bus speed affects results

🎨 Step 6: Creating Custom Benchmarks

Using the Arsenal API

import { usePerformanceArsenal } from '@bun/performance-arsenal';

// In your React component
function CustomBenchmark() {
  const {
    runBenchmark,
    benchmarkResults,
    isRunning,
    hardwareInfo
  } = usePerformanceArsenal();

  const handleCustomBenchmark = async () => {
    // Define your custom benchmark
    const customTest = {
      name: 'Custom Algorithm',
      iterations: 1000,
      setup: () => {
        // Initialize test data
        return { data: generateLargeDataset() };
      },
      run: (context) => {
        // Run your algorithm
        return processData(context.data);
      }
    };

    await runBenchmark(customTest);
  };

  return (
    <div>
      <button onClick={handleCustomBenchmark} disabled={isRunning}>
        Run Custom Benchmark
      </button>

      {benchmarkResults && (
        <div>
          <h3>Results: {benchmarkResults.name}</h3>
          <p>Duration: {benchmarkResults.duration}ms</p>
          <p>Operations/sec: {benchmarkResults.opsPerSecond}</p>
        </div>
      )}
    </div>
  );
}

Benchmark Best Practices

Test Setup

const benchmarkConfig = {
  // Warm-up phase
  warmup: 100,

  // Main test iterations
  iterations: 1000,

  // Statistical significance
  minSamples: 5,
  maxSamples: 20,

  // Confidence interval
  confidenceLevel: 0.95
};

Result Validation

function validateResults(results) {
  // Check for statistical significance
  const mean = results.reduce((a, b) => a + b) / results.length;
  const stdDev = Math.sqrt(
    results.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / results.length
  );

  // Ensure results are consistent (low coefficient of variation)
  const cv = stdDev / mean;
  return cv < 0.1; // Less than 10% variation
}

πŸ”§ Step 7: Performance Optimization

Based on Benchmark Results

CPU Optimization

// Use Bun's native performance features
const crypto = Bun.CryptoHasher;

// Leverage Web Workers for heavy computation
const worker = new Worker('computation-worker.ts');

// Optimize algorithms
function optimizedAlgorithm(data) {
  // Use efficient data structures
  const map = new Map(); // O(1) lookups
  // Avoid nested loops where possible
  // Use Bun.Array for large arrays
}

Memory Optimization

// Explicit garbage collection when needed
if (Bun.gc) {
  Bun.gc(true); // Force major GC cycle
}

// Use efficient data structures
const buffer = new Bun.ArrayBuffer(size);
const view = new DataView(buffer);

// Stream processing for large files
const file = Bun.file('large-dataset.json');
for await (const chunk of file.stream()) {
  processChunk(chunk);
}

I/O Optimization

// Use Bun's fast HTTP client
const response = await fetch('https://api.example.com/data');

// Parallel requests
const promises = urls.map(url => fetch(url));
const results = await Promise.all(promises);

// File system operations
const files = await Bun.glob('**/*.ts');
const contents = await Promise.all(
  files.map(file => Bun.file(file).text())
);

πŸ“ˆ Step 8: Continuous Performance Monitoring

Analytics Integration

import { usePerformanceMonitor } from '@bun/performance-arsenal';

function AppWithAnalytics() {
  const { fps, memoryUsage, trackBenchmark } = usePerformanceMonitor();

  // Track key user interactions
  const handleUserAction = () => {
    trackBenchmark('user-action', {
      action: 'button-click',
      timestamp: Date.now(),
      fps: fps,
      memory: memoryUsage
    });
  };

  return (
    <div>
      <p>FPS: {fps}</p>
      <p>Memory: {memoryUsage}MB</p>
      <button onClick={handleUserAction}>
        Track Performance
      </button>
    </div>
  );
}

Performance Budgets

const performanceBudgets = {
  // Runtime performance
  fps: { min: 30, target: 60 },
  memoryUsage: { max: 100 }, // MB

  // Load performance
  firstPaint: { max: 1000 }, // ms
  largestContentfulPaint: { max: 2500 }, // ms

  // Bundle size
  bundleSize: { max: 500 }, // KB
  vendorSize: { max: 200 } // KB
};

function checkBudgets(metrics) {
  const violations = [];

  if (metrics.fps < performanceBudgets.fps.min) {
    violations.push(`FPS too low: ${metrics.fps}`);
  }

  if (metrics.memoryUsage > performanceBudgets.memoryUsage.max) {
    violations.push(`Memory usage too high: ${metrics.memoryUsage}MB`);
  }

  return violations;
}

🎯 Tutorial Summary

What You Learned

βœ… Basic benchmarking with Arsenal Lab's interface βœ… Performance analysis across different workloads βœ… Bun vs Node.js comparison techniques βœ… Custom benchmark creation with the Arsenal API βœ… Performance optimization strategies βœ… Continuous monitoring setup

Key Takeaways

  1. Benchmarks are contextual - Test real-world scenarios
  2. Consistency matters - Look for stable performance across runs
  3. Hardware influences results - Understand your testing environment
  4. Optimization is iterative - Measure, optimize, measure again
  5. Monitoring continues post-optimization - Performance is ongoing

Next Steps

πŸ† Achievement Unlocked!

Performance Testing Pro πŸŽ–οΈ You've completed the comprehensive performance testing tutorial and learned to:

  • Run sophisticated benchmarks
  • Analyze performance data
  • Create custom tests
  • Optimize applications
  • Monitor performance continuously

πŸ“š Additional Resources

Arsenal Lab Features

External Resources


Ready for more? Try the Database Integration Tutorial to learn about database performance testing.

Questions? Join our GitHub Discussions or check the Troubleshooting Guide.

Built with ❀️ for the Bun ecosystem β€’ Last updated: October 21, 2025

Clone this wiki locally