This document explains how to run and interpret performance benchmarks for the Image Color Palette Extractor WebAssembly library.
Before running benchmarks, ensure you have:
- Rust - Install from rustup.rs
- Criterion - Added as dev dependency (automatically installed)
This project includes two comprehensive benchmark suites:
Comprehensive performance testing covering:
- Size Scaling: Performance across different image sizes (32x32 to 512x512)
- Color Count Impact: How different k values (1-32 colors) affect performance
- Pattern Complexity: Performance with different image patterns (solid, gradient, random, etc.)
- Configuration Impact: Effect of max_iterations and convergence settings
- Utility Functions: Performance of color distance, sorting, and filtering
- Memory Usage: Memory allocation patterns
- Regression Testing: Consistent baseline measurements
Quick performance checks for core operations:
- Color creation and conversion
- Distance calculations
- Small palette extractions
- Format conversions (hex, RGB strings)
.\run-benchmarks.ps1chmod +x run-benchmarks.sh
./run-benchmarks.sh# Run all benchmarks
cargo bench
# Run only full benchmarks
cargo bench --bench palette_extraction
# Run only micro benchmarks
cargo bench --bench micro_benchmarks
# Run specific benchmark groups
cargo bench palette_extraction_by_size
cargo bench utility_functions
cargo bench micro_benchmarksbenches/
├── palette_extraction.rs # Comprehensive benchmarks
└── micro_benchmarks.rs # Quick performance checks
target/criterion/ # Generated benchmark results
├── report/ # HTML reports
└── */base/ # Raw benchmark data
Criterion provides detailed statistics:
palette_extraction_by_size/random_image/128x128
time: [45.234 ms 45.892 ms 46.621 ms]
thrpt: [351.88 Kelem/s 357.42 Kelem/s 362.54 Kelem/s]
Key Metrics:
- Time: How long the operation takes
- Throughput: Elements processed per second
- Confidence Intervals: Statistical reliability ranges
- Small images (32x32): < 1ms
- Medium images (128x128): < 50ms
- Large images (256x256): < 200ms
- Small images: 1-5ms
- Medium images: 50-100ms
- Large images: 200-500ms
- Small images: > 5ms
- Medium images: > 100ms
- Large images: > 500ms
cargo bench palette_extraction_by_sizeTests how performance scales with image size.
Expected Results:
- Linear scaling with pixel count
- Throughput should remain relatively stable
cargo bench palette_extraction_by_k_colorsTests performance with different numbers of extracted colors.
Expected Results:
- Slight increase in time with more colors
- K=1 (dominant color) should be fastest
cargo bench palette_extraction_by_patternTests how image complexity affects performance.
Expected Results:
- Solid colors: Fastest (early convergence)
- Random patterns: Slowest (requires full iterations)
- Gradients/bands: Medium performance
cargo bench extractor_configurationTests how algorithm settings affect performance.
Key Insights:
- Higher max_iterations = longer runtime
- Lower convergence threshold = more iterations
- Find optimal balance for your use case
cargo bench utility_functionsTests performance of helper functions.
Critical Functions:
color_distance_rgb: Should be sub-microsecondsort_colors_by_luminance: Scales with O(n log n)remove_similar_colors: Scales with O(n²)
- Batch Processing: Process multiple images together
- Optimal K Values: Use k=5-8 for best balance
- Configuration Tuning:
- max_iterations: 20 (default is good)
- convergence: 5.0 (default is good)
- Pre-filtering: Remove similar colors before palette extraction
- Image Size: Resize large images before processing
- Color Count: Request fewer colors for faster processing
- Caching: Cache results for identical images
- Progressive Enhancement: Start with dominant color, add more as needed
# Save current performance as baseline
cargo bench -- --save-baseline before_optimization
# After changes, compare to baseline
cargo bench -- --baseline before_optimization# In CI/CD, fail if performance degrades by >10%
cargo bench -- --baseline main --threshold 10Criterion generates detailed HTML reports in target/criterion/report/index.html.
- Summary: Overall performance overview
- Individual Benchmarks: Detailed timing analysis
- Plots: Visual performance trends
- Comparisons: Before/after analysis
- Statistics: Confidence intervals and outliers
- PDF Plot: Distribution of measurement times
- Regression Plot: Performance over iterations
- Mean Plot: Average performance with confidence intervals
name: Performance Benchmarks
on: [push, pull_request]
jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Run benchmarks
run: cargo bench --bench micro_benchmarks
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: benchmark-results
path: target/criterion/For detailed memory analysis:
# Install valgrind (Linux) or Instruments (macOS)
cargo bench --bench palette_extraction -- --profile-time=10
# Or use cargo instruments on macOS
cargo instruments -t "Time Profiler" --bench palette_extraction| Operation | Image Size | Target Time | Notes |
|---|---|---|---|
| Dominant Color | 128x128 | < 10ms | Single color extraction |
| 5-Color Palette | 128x128 | < 50ms | Standard use case |
| 8-Color Palette | 256x256 | < 200ms | Large image processing |
| Color Distance | Any | < 1μs | Utility function |
| Hex Conversion | Any | < 100ns | Format conversion |
- Linear with pixels: 2x pixels ≈ 2x time
- Sub-linear with colors: 2x colors ≈ 1.5x time
- Constant utilities: Independent of input size
- Check CPU load: Ensure system isn't under load
- Disable power management: Use high-performance mode
- Close other applications: Minimize background processes
- Run multiple times: Average results over several runs
- System noise: Use
--warm-up-timeand--measurement-time - Thermal throttling: Monitor CPU temperature
- Memory pressure: Ensure sufficient RAM
- Background tasks: Disable automatic updates
# Clean and rebuild
cargo clean
cargo bench
# Update dependencies
cargo updateWhen submitting performance improvements:
- Run full benchmark suite before and after changes
- Include performance comparison in PR description
- Document any trade-offs (speed vs accuracy)
- Test across different scenarios (image sizes, patterns)
- Verify memory usage doesn't increase significantly
To add new benchmarks, create functions in benches/palette_extraction.rs:
fn bench_your_feature(c: &mut Criterion) {
let mut group = c.benchmark_group("your_feature");
group.bench_function("test_case", |b| {
b.iter(|| {
// Your benchmark code here
black_box(your_function(black_box(input)))
});
});
group.finish();
}
// Add to criterion_group! macro
criterion_group!(benches, bench_your_feature, /* ... other benchmarks */);For deeper analysis, export raw data:
# Export to CSV
cargo bench -- --output-format csv > results.csv
# Custom analysis with external tools
python analyze_performance.py results.csv