# Wasot Performance Profiling Guide

Complete guide to performance measurement, profiling, and optimization tools.

## Quick Reference

```bash
# Benchmark (quick)
./scripts/benchmark_cli.py --quick

# Benchmark with large files
./scripts/benchmark_cli.py --large
./scripts/benchmark_cli.py --extra 50GB

# Generate test files
python3 ./scripts/generators/generate_large_file.py -o data/bench/50gb.wasot -s 50GB

# Profile memory (DHAT)
./scripts/profile.py

# Visualize benchmark history
./scripts/plot_benchmarks.py -o benchmark_history.png
```

## Tools Overview

| Tool | Purpose | Command |
|------|---------|---------|
| `benchmark_cli.py` | Performance measurement | `./scripts/benchmark_cli.py --quick` |
| `profile.py` | DHAT heap profiling | `./scripts/profile.py` |
| `plot_benchmarks.py` | Visualize benchmark history | `./scripts/plot_benchmarks.py` |
| `generate_large_file.py` | Generate test files | `python3 ./scripts/generators/generate_large_file.py -s 1GB` |
| `test_memory_usage.py` | Memory usage analysis | `./scripts/test_memory_usage.py` |
| `flamegraph` | CPU profiling | `flamegraph -- ./target/release/wasot ...` |
| `samply` | Interactive CPU profiler | `samply record ./target/release/wasot ...` |

---

## Benchmarking

### benchmark_cli.py

Main benchmarking tool. Measures throughput in lines/second.

```bash
# Quick benchmark (1 run each, no storage)
./scripts/benchmark_cli.py --quick

# Full benchmark (5 runs, stores results)
./scripts/benchmark_cli.py

# With performance assertions (fails if too slow)
./scripts/benchmark_cli.py --quick --assert

# Specific sizes only
./scripts/benchmark_cli.py --sizes 1mb 100mb

# Include large files (1GB, 4GB)
./scripts/benchmark_cli.py --large

# Custom extra-large file (reuses existing if found)
./scripts/benchmark_cli.py --extra 50GB

# Force regenerate test files
./scripts/benchmark_cli.py --regenerate

# Multiple output formats
./scripts/benchmark_cli.py --formats wasot,xml,jsonl
```

**Options:**
- `--quick` - Single run, no file storage, prints report
- `--assert` - Check performance assertions, exit 1 if failed
- `--large` - Include 1GB and 4GB files (1 run each)
- `--extra SIZE` - Add custom size (e.g., 50GB), reuses existing file
- `--sizes` - Specify which sizes to benchmark
- `--formats` - Comma-separated output formats to test
- `--regenerate` - Force regenerate test files
- `--runs N` - Number of runs per test (default: 5)

**Standard sizes:** 1kb, 10kb, 500kb, 1mb, 100mb
**Large sizes:** 1gb, 4gb (with `--large`)

### plot_benchmarks.py

Visualize benchmark progression over time.

```bash
# Plot to screen (interactive)
./scripts/plot_benchmarks.py

# Save to file
./scripts/plot_benchmarks.py -o benchmark_history.png

# Export as CSV
./scripts/plot_benchmarks.py --csv -o benchmarks.csv

# Plot specific sizes
./scripts/plot_benchmarks.py --sizes 1mb 100mb

# Plot duration instead of rate
./scripts/plot_benchmarks.py --metric duration

# List available benchmark files
./scripts/plot_benchmarks.py --list
```

---

## Test File Generation

### generate_large_file.py

Generate wasot test files of any size.

```bash
# Generate specific size
python3 ./scripts/generators/generate_large_file.py -o data/bench/50gb.wasot -s 50GB

# Size formats: 1KB, 10MB, 1GB, etc.
python3 ./scripts/generators/generate_large_file.py -o test.wasot -s 500MB

# The benchmark script auto-generates standard sizes
./scripts/benchmark_cli.py  # Creates 1kb, 10kb, 500kb, 1mb, 100mb
```

**Tip:** Large files (>1GB) take a long time to generate. The benchmark script reuses existing files automatically.

---

## Memory Profiling

### profile.py (DHAT)

Analyze heap allocations to find memory hotspots.

```bash
# Profile with default file (1mb.wasot)
./scripts/profile.py

# Profile specific file
./scripts/profile.py --file data/bench/100mb.wasot

# Analyze existing dhat-heap.json
./scripts/profile.py --analyze

# Compare two profiles
./scripts/profile.py --compare before.json after.json
```

**What to look for:**
- High `tb` (total bytes) = allocation hotspots
- Look at call stacks to find source
- Repeated same-size allocations = missing caching

### Manual DHAT

```bash
# Build with DHAT support
cargo build --release --bin wasot --features dhat-heap

# Run (creates dhat-heap.json)
./target/release/wasot data/bench/1mb.wasot -t wasot > /dev/null

# View in browser
# Open: https://nicola.ac/dhat-viewer/
```

### test_memory_usage.py

Quick memory usage check.

```bash
./scripts/test_memory_usage.py data/bench/100mb.wasot
```

---

## CPU Profiling

### Flamegraph

Visual CPU profile showing where time is spent.

```bash
# Enable profiling (needs sudo once)
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid

# Build with debug symbols
CARGO_PROFILE_RELEASE_DEBUG=true CARGO_PROFILE_RELEASE_STRIP=false \
    cargo build --release --bin wasot

# Generate flamegraph
flamegraph -o flamegraph.svg -- ./target/release/wasot data/bench/1mb.wasot -t wasot

# Open in browser
firefox flamegraph.svg
```

### Samply

Interactive web-based CPU profiler.

```bash
# Profile and open in browser
samply record ./target/release/wasot data/bench/1mb.wasot -t wasot

# Save profile for later
samply record --save-only -o profile.json -- ./target/release/wasot data/bench/1mb.wasot
```

---

## Micro-benchmarks

### Criterion

For testing specific functions.

```bash
# Run all benchmarks
cargo bench

# Run specific benchmark
cargo bench base36
```

---

## Typical Workflow

### 1. Measure Baseline
```bash
./scripts/benchmark_cli.py --quick
```

### 2. Profile to Find Hotspots
```bash
./scripts/profile.py --file data/bench/100mb.wasot
```

### 3. Identify Issues
Look for:
- High total bytes (`tb`) in DHAT output
- Wide bars in flamegraph
- Regex compilation in loops
- Unnecessary string allocations

### 4. Fix and Verify
```bash
# Make changes, then re-benchmark
./scripts/benchmark_cli.py --quick

# Compare allocations
./scripts/profile.py --compare before.json after.json
```

### 5. Visualize Progress
```bash
./scripts/plot_benchmarks.py -o progress.png
```

---

## Performance Targets

| File Size | Lines | Target Time | Target Rate |
|-----------|-------|-------------|-------------|
| 1 KB | ~32 | < 10ms | > 3K lines/s |
| 10 KB | ~240 | < 20ms | > 10K lines/s |
| 1 MB | ~22K | < 50ms | > 500K lines/s |
| 100 MB | ~2.2M | < 2s | > 1M lines/s |
| 1 GB | ~22M | < 20s | > 1M lines/s |

Current performance: **2.5M lines/second** on 100MB files.

---

## Installation

```bash
# Install Rust profiling tools
cargo install samply flamegraph

# For flamegraph, install perf
sudo apt install linux-tools-generic  # Debian/Ubuntu

# Python dependencies (in project venv)
uv pip install matplotlib tqdm
```

---

## See Also

- `docs/performance_tips.md` - Optimization patterns specific to wasot
- `docs/memory_profiling.md` - Detailed memory analysis
- `reports/` - Performance analysis reports
- `benches/` - Criterion micro-benchmarks
