string_pipeline 0.13.4

A flexible, template-driven string transformation pipeline for Rust.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
# ๐Ÿ† String Pipeline Benchmarking Tool

_NOTE: what follows has mostly been assembled using AI as an experiment and as a basis for further improvements._

A simple benchmarking tool that helps measure performance of string pipeline operations and provides timing information in both text and JSON formats.

## ๐Ÿ“‹ Table of Contents

- [๐Ÿš€ Quick Start]#-quick-start
- [โœจ Features Overview]#-features-overview
- [๐Ÿ“– Usage Guide]#-usage-guide
  - [Basic Usage]#basic-usage
  - [Command Line Options]#command-line-options
  - [Output Formats]#output-formats
- [๐Ÿงช Benchmark Categories]#-benchmark-categories
  - [Single Operations]#1--single-operations
  - [Multiple Simple Operations]#2--multiple-simple-operations
  - [Map Operations]#3-๏ธ-map-operations
  - [Complex Operations]#4--complex-operations
- [๐Ÿ“Š Test Data & Methodology]#-test-data--methodology
- [๐Ÿ“ˆ Performance Analysis]#-performance-analysis
  - [Basic Methods]#basic-methods
  - [Timing Precision]#timing-precision
  - [Metrics Explanation]#metrics-explanation
- [๐Ÿ’ผ Automated Usage]#-automated-usage
  - [Script Integration]#script-integration
  - [Performance Comparison]#performance-comparison
- [๐Ÿ”ง Development Guide]#-development-guide
  - [Adding New Benchmarks]#adding-new-benchmarks
  - [Performance Considerations]#performance-considerations
  - [Best Practices]#best-practices
- [๐Ÿ“‹ Example Results]#-example-results
- [โš ๏ธ Troubleshooting]#๏ธ-troubleshooting

## ๐Ÿš€ Quick Start

```bash
# Run with default settings (1000 iterations, text output)
cargo run --bin bench

# Run in release mode for better performance
cargo run --release --bin bench

# Quick test with fewer iterations
cargo run --bin bench -- --iterations 100
```

## โœจ Features Overview

- ๐Ÿงช **Test Coverage**: Tests single operations, multiple operations, map operations, and complex nested operations
- ๐Ÿ“Š **Basic Statistics**: Runs configurable iterations (default 1000) and calculates averages with outlier removal
- ๐Ÿ‹๏ธ **Warmup Phase**: Runs warmup iterations (10% of measurements) to help get consistent timing
- ๐ŸŽฏ **Outlier Removal**: Removes top and bottom 5% of measurements to reduce noise
- ๐Ÿ“„ **Multiple Output Formats**: Supports both human-readable text and machine-readable JSON output
- ๐Ÿ—๏ธ **Performance Categories**: Groups results by operation type for easier analysis
- ๐Ÿ“ˆ **Basic Metrics**: Provides average, minimum, maximum times from the filtered measurements
- โšก **Automation Support**: Works well in CI/CD and automated scripts
- ๐Ÿ” **Debug Integration**: Works with the existing debug system's timing capabilities

## ๐Ÿ“– Usage Guide

### Basic Usage

| Command | Description | Use Case |
|---------|-------------|----------|
| `cargo run --bin bench` | Default run (1000 iterations, text) | Development testing |
| `cargo run --release --bin bench` | Optimized build | Better performance measurements |
| `./target/release/bench.exe` | Direct binary execution | Scripts and automation |

```bash
# ๐Ÿš€ Development workflow
cargo run --bin bench -- --iterations 100  # Quick test

# ๐Ÿ”„ More thorough testing
cargo build --release --bin bench
./target/release/bench --iterations 5000 --format json > results.json
```

### Command Line Options

| Option | Short | Default | Description |
|--------|-------|---------|-------------|
| `--iterations` | `-n` | `1000` | Number of iterations per benchmark |
| `--format` | `-f` | `text` | Output format: `text` or `json` |
| `--help` | `-h` | - | Show help information |
| `--version` | `-V` | - | Show version information |

**Examples:**

```bash
# ๐Ÿ“Š Better accuracy (more iterations)
cargo run --bin bench -- --iterations 2000

# ๐Ÿค– Machine processing (JSON output)
cargo run --bin bench -- --format json

# ๐Ÿš€ Quick development test
cargo run --bin bench -- --iterations 50 --format text

# ๐Ÿ” Help and version info
cargo run --bin bench -- --help
cargo run --bin bench -- --version
```

### Output Formats

#### ๐Ÿ“„ Text Output (Default)

Good for **reading results** and **development workflows**:

- โœ… **Progress indicators** during execution with real-time feedback
- โœ… **Formatted tables** with aligned columns and readable timing units
- โœ… **Performance summary** by category with fastest/slowest identification
- โœ… **Basic statistics** including total execution time and outlier counts
- โœ… **Color-coded** output (when terminal supports it)

```text
๐Ÿ”ธ Running single operation benchmarks...
  Single: upper ... โœ“ avg: 295ns
  Single: lower ... โœ“ avg: 149ns

๐Ÿ“Š Summary:
โ€ข Total benchmarks run: 33
โ€ข Total execution time: 392.17ms
```

#### ๐Ÿค– JSON Output

Good for **automation**, **scripts**, and **data processing**:

- โœ… **Machine-readable** structured data
- โœ… **Timestamps** and version information for tracking
- โœ… **Timing metrics** for each benchmark
- โœ… **Categorized results** for easier filtering
- โœ… **Works well** with tools like `jq`, `python`, etc.

```json
{
  "summary": {
    "total_benchmarks": 33,
    "total_execution_time_ns": 392170000,
    "iterations_per_benchmark": 1000
  },
  "categories": {
    "single_operations": [...],
    "map_operations": [...]
  },
  "timestamp": "2024-01-15T10:30:45Z",
  "version": "0.13.2"
}
```

## ๐Ÿงช Benchmark Categories

The benchmark suite is organized into **four distinct categories** that test different aspects of the pipeline system, from basic operations to complex nested transformations.

### 1. ๐Ÿ”ง Single Operations

Tests **individual pipeline operations** to establish baseline performance:

| Operation | Template | Purpose | Expected Performance |
|-----------|----------|---------|---------------------|
| `split` | `{split:,:..\|join:,}` | Text splitting capability | ~3-4ฮผs |
| `upper` | `{upper}` | Case conversion | ~200-300ns |
| `lower` | `{lower}` | Case conversion | ~150-200ns |
| `trim` | `{trim}` | Whitespace removal | ~100-150ns |
| `reverse` | `{reverse}` | String/list reversal | ~600-700ns |
| `sort` | `{split:,:..\|sort\|join:,}` | Alphabetical sorting | ~3-4ฮผs |
| `unique` | `{split:,:..\|unique\|join:,}` | Duplicate removal | ~5-6ฮผs |
| `replace` | `{replace:s/a/A/g}` | Pattern replacement | ~2-3ฮผs |
| `filter` | `{split:,:..\|filter:^[a-m]\|join:,}` | Pattern filtering | ~14-16ฮผs |

> ๐Ÿ’ก **Baseline Importance:** These measurements establish the **fundamental performance characteristics** of each operation and serve as building blocks for understanding more complex pipeline performance.

### 2. ๐Ÿ”— Multiple Simple Operations

Tests **chains of basic operations** to measure composition overhead:

| Pipeline | Template | Purpose | Performance Range |
|----------|----------|---------|------------------|
| Split + Join | `{split:,:..\|join: }` | Basic transformation | ~3ฮผs |
| Split + Sort + Join | `{split:,:..\|sort\|join:;}` | Sorting pipeline | ~3-4ฮผs |
| Split + Unique + Join | `{split:,:..\|unique\|join:,}` | Deduplication | ~5-6ฮผs |
| Split + Reverse + Join | `{split:,:..\|reverse\|join:-}` | Reversal pipeline | ~3ฮผs |
| Split + Filter + Join | `{split:,:..\|filter:^[a-m]\|join:,}` | Filtering pipeline | ~16-17ฮผs |
| Split + Slice + Join | `{split:,:..\|slice:0..5\|join:&}` | Range extraction | ~4ฮผs |
| Upper + Trim + Replace | `{upper\|trim\|replace:s/,/ /g}` | String transformations | ~3-4ฮผs |
| Split + Sort + Unique + Join | `{split:,:..\|sort\|unique\|join:+}` | Multi-step processing | ~5-6ฮผs |

> ๐ŸŽฏ **Composition Analysis:** These tests reveal how **operation chaining affects performance** and whether there are significant overhead costs in pipeline composition.

### 3. ๐Ÿ—บ๏ธ Map Operations

Tests **operations applied to each list item** via the map function:

| Operation Type | Template | Purpose | Performance Range |
|----------------|----------|---------|------------------|
| Map(Upper) | `{split:,:..\|map:{upper}\|join:,}` | Case conversion mapping | ~8-9ฮผs |
| Map(Trim+Upper) | `{split:,:..\|map:{trim\|upper}\|join: }` | Chained operations in map | ~9-10ฮผs |
| Map(Prepend) | `{split:,:..\|map:{prepend:item}\|join:,}` | Text prefix addition | ~9-10ฮผs |
| Map(Append) | `{split:,:..\|map:{append:-fruit}\|join:;}` | Text suffix addition | ~10-11ฮผs |
| Map(Reverse) | `{split:,:..\|map:{reverse}\|join:,}` | String reversal per item | ~8-9ฮผs |
| Map(Substring) | `{split:,:..\|map:{substring:0..3}\|join: }` | Text extraction per item | ~8-9ฮผs |
| Map(Pad) | `{split:,:..\|map:{pad:10:_}\|join:,}` | Text padding per item | ~10-11ฮผs |
| Map(Replace) | `{split:,:..\|map:{replace:s/e/E/g}\|join:,}` | Pattern replacement per item | ~49-60ฮผs |

> ๐Ÿ” **Map Performance:** Map operations show **scaling behavior** based on list size and the complexity of the inner operation. Replace operations are notably slower due to regex processing.

### 4. ๐Ÿš€ Complex Operations

Tests **sophisticated nested operations** and real-world transformation scenarios:

| Complexity Level | Template | Purpose | Performance Range |
|------------------|----------|---------|------------------|
| Nested Split+Join | `{split:,:..\|map:{split:_:..\|join:-}\|join: }` | Multi-level parsing | ~15-16ฮผs |
| Combined Transform | `{split:,:..\|map:{upper\|substring:0..5}\|join:,}` | Chained transformations | ~10ฮผs |
| Filter+Map Chain | `{split:,:..\|filter:^[a-m]\|map:{reverse}\|join:&}` | Conditional processing | ~16-17ฮผs |
| Replace+Transform | `{split:,:..\|map:{upper\|replace:s/A/a/g}\|join:;}` | Pattern + transformation | ~50-60ฮผs |
| Unique+Map | `{split:,:..\|unique\|map:{upper}\|join:,}` | Dedup + transformation | ~10-11ฮผs |
| Multi-Replace | `{split:,:..\|map:{replace:s/a/A/g\|upper}\|join:,}` | Complex pattern work | ~51-60ฮผs |
| Substring+Pad | `{split:,:..\|map:{substring:0..3\|pad:5:_}\|join:+}` | Text formatting pipeline | ~10-11ฮผs |
| Multi-Level Filter | `{split:,:..\|filter:^[a-z]\|map:{upper}\|sort\|join: }` | Comprehensive processing | ~17-18ฮผs |

> ๐Ÿ† **Real-World Scenarios:** Complex operations represent **typical production use cases** and help identify performance bottlenecks in sophisticated data transformation pipelines.

## ๐Ÿ“Š Test Data & Methodology

### ๐ŸŽ Test Dataset

The benchmark uses a **carefully designed test dataset** that provides realistic performance characteristics:

| Property | Value | Purpose |
|----------|-------|---------|
| **Content** | Comma-separated fruit names | Real-world data structure |
| **Length** | 208 characters | Moderate size for consistent timing |
| **Items** | 26 distinct fruits | Good sample size |
| **Unicode** | ASCII + Unicode safe | Comprehensive character handling |
| **Separators** | Commas, underscores, pipes | Multiple parsing scenarios |

**Actual Test Data:**

```text
"apple,banana,cherry,date,elderberry,fig,grape,honeydew,ice_fruit,jackfruit,kiwi,lemon,mango,nectarine,orange,papaya,quince,raspberry,strawberry,tomato,ugli_fruit,vanilla,watermelon,xigua,yellow_apple,zucchini"
```

> ๐ŸŽฏ **Why This Dataset?** This data provides **realistic performance characteristics** without being too large to cause timing inconsistencies or too small to provide meaningful measurements.

## ๐Ÿ“ˆ Performance Analysis

### Basic Methods

#### ๐Ÿ‹๏ธ Warmup Phase

The benchmark includes a **warmup phase** to help get more consistent measurements by reducing cold-start effects:

| Step | Process | Rationale |
|------|---------|-----------|
| 1. **Warmup Calculation** | Calculate 10% of measurement iterations | Proportional to test size |
| 2. **Cache Warming** | Run operations without timing measurement | Prime CPU caches and memory |
| 3. **System Stabilization** | Allow CPU frequency scaling to settle | More consistent conditions |
| 4. **Memory Allocation** | Pre-allocate common data structures | Reduce allocation overhead |

```rust
// Warmup phase implementation
fn benchmark_template(&self, name: &str, template_str: &str) -> BenchmarkResult {
    let template = Template::parse(template_str)?;

    // Warmup phase - run operations without timing
    for _ in 0..self.warmup_iterations {
        let _ = template.format(&self.test_data)?;
    }

    // Actual measurement phase begins here...
}
```

> ๐ŸŽฏ **Warmup Benefits:** Helps reduce timing variations by reducing cold cache effects and system instability.

#### ๐ŸŽฏ Outlier Removal

The benchmark uses a **simple approach** to reduce measurement noise:

| Step | Process | Rationale |
|------|---------|-----------|
| 1. **Data Collection** | Collect all timing measurements | Raw performance data |
| 2. **Sorting** | Sort measurements by duration | Prepare for filtering |
| 3. **Filtering** | Remove top & bottom 5% | Remove timing outliers |
| 4. **Average Calculation** | Calculate mean of remaining 90% | More stable average |
| 5. **Reporting** | Report outliers removed count | Show what was filtered |

```rust
// Simplified outlier removal algorithm
fn remove_outliers(mut times: Vec<Duration>) -> (Vec<Duration>, usize) {
    times.sort();
    let len = times.len();
    let outlier_count = (len as f64 * 0.05).ceil() as usize;

    let start_idx = outlier_count;
    let end_idx = len - outlier_count;

    let filtered = times[start_idx..end_idx].to_vec();
    let outliers_removed = times.len() - filtered.len();

    (filtered, outliers_removed)
}
```

> ๐Ÿ“Š **Simple Approach:** This basic filtering helps reduce noise in timing measurements, similar to what other benchmarking tools do.

### Timing Precision

#### โšก Timing Details

| Feature | Implementation | Benefit |
|---------|----------------|---------|
| **Resolution** | Nanosecond precision via `std::time::Instant` | Good for fast operations |
| **Overhead** | Small timing overhead (~10-20ns) | Minimal impact on results |
| **Platform** | Cross-platform timing support | Works across systems |
| **Formatting** | Automatic unit selection (ns/ฮผs/ms/s) | Easy to read output |

#### ๐Ÿ“ Unit Formatting Algorithm

```rust
fn format_duration(duration: Duration) -> String {
    let nanos = duration.as_nanos();
    if nanos < 1_000 {
        format!("{}ns", nanos)
    } else if nanos < 1_000_000 {
        format!("{:.2}ฮผs", nanos as f64 / 1_000.0)
    } else if nanos < 1_000_000_000 {
        format!("{:.2}ms", nanos as f64 / 1_000_000.0)
    } else {
        format!("{:.2}s", duration.as_secs_f64())
    }
}
```

### Metrics Explanation

#### ๐Ÿ“Š Core Metrics

| Metric | Description | Interpretation |
|--------|-------------|----------------|
| **Average** | Mean time after outlier removal | Main performance indicator |
| **Min** | Fastest measurement after outlier removal | Best-case timing |
| **Max** | Slowest measurement after outlier removal | Worst-case timing |
| **Iterations** | Number of measurement runs performed | How many times we measured |
| **Warmup** | Number of pre-measurement runs | System preparation cycles |

#### ๐ŸŽฏ Performance Ranges

| Performance Level | Time Range | Operations |
|------------------|------------|------------|
| **Ultra Fast** | < 1ฮผs | `upper`, `lower`, `trim` |
| **Fast** | 1-10ฮผs | `split`, `join`, `sort`, basic chains |
| **Moderate** | 10-50ฮผs | `map` operations, complex chains |
| **Intensive** | > 50ฮผs | `replace` operations, regex processing |

> ๐Ÿ’ก **Iteration Guidelines:**
>
> - **Development**: 50-100 iterations for quick feedback
> - **Automation**: 500-1000 iterations for better reliability
> - **Thorough testing**: 2000-5000 iterations for more stable results

## ๐Ÿ“‹ Example Results

### ๐Ÿ“Š Text Output Sample

```text
๐Ÿ”ธ Running single operation benchmarks...
  Single: split ... โœ“ avg: 3.53ฮผs
  Single: upper ... โœ“ avg: 295ns
  Single: lower ... โœ“ avg: 149ns

๐Ÿ”ธ Running multiple simple operations benchmarks...
  Multi: split + join ... โœ“ avg: 3.12ฮผs
  Multi: split + sort + join ... โœ“ avg: 3.47ฮผs

================================================================================
                          BENCHMARK RESULTS
================================================================================

๐Ÿ“Š Summary:
โ€ข Total benchmarks run: 33
โ€ข Total execution time: 392.17ms
โ€ข Measurement iterations per benchmark: 1000
โ€ข Warmup iterations per benchmark: 100 (10% of measurements)

๐Ÿ“ˆ Detailed Results:
Benchmark                                               Average          Min          Max
----------------------------------------------------------------------------------------
Single: upper                                             295ns        200ns       380ns
Single: lower                                             149ns        120ns       180ns
Map: split + map(replace) + join                        49.16ฮผs      42.90ฮผs      55.80ฮผs

๐Ÿ“‹ Performance by Category:
๐Ÿ”น Single Operations (9 tests)
   Average: 3.31ฮผs | Fastest: 136ns (trim) | Slowest: 14.03ฮผs (filter)

๐Ÿ”น Map Operations (8 tests)
   Average: 14.22ฮผs | Fastest: 8.35ฮผs (map(upper)) | Slowest: 49.16ฮผs (map(replace))
```

### ๐Ÿค– JSON Output Sample

```json
{
  "summary": {
    "total_benchmarks": 33,
    "total_execution_time_ns": 392170000,
    "total_execution_time_formatted": "392.17ms",
    "iterations_per_benchmark": 1000,
    "outlier_removal_method": "Top and bottom 5% removed",
    "warmup_iterations_per_benchmark": 100
  },
  "categories": {
    "single_operations": [
      {
        "name": "Single: upper",
        "iterations": 1000,
        "average_time_ns": 295000,
        "average_time_formatted": "295ns",
        "min_time_ns": 200000,
        "min_time_formatted": "200ns",
        "max_time_ns": 9100000,
        "max_time_formatted": "9.10ฮผs",
        "outliers_removed": 100,
        "total_raw_measurements": 1000
      }
    ]
  },
  "timestamp": "2024-01-15T10:30:45Z",
  "version": "0.13.2"
}
```

## ๐Ÿ’ผ Automated Usage

### Script Integration

#### ๐Ÿš€ GitHub Actions Example

```yaml
name: Performance Benchmarks
on: [push, pull_request]

jobs:
  benchmark:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Build benchmark tool
        run: cargo build --release --bin bench
      - name: Run benchmarks
        run: |
          ./target/release/bench --iterations 5000 --format json > benchmark_results.json
      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: benchmark-results
          path: benchmark_results.json
```

#### ๐Ÿ” Processing Results with jq

```bash
# Extract summary information
cat benchmark_results.json | jq '.summary'

# Get average times for single operations
cat benchmark_results.json | jq '.categories.single_operations[].average_time_formatted'

# Find slowest operations
cat benchmark_results.json | jq -r '.categories[] | .[] | "\(.name): \(.average_time_formatted)"' | sort -V

# Performance alerts (fail if any operation > 100ฮผs)
SLOW_OPS=$(cat benchmark_results.json | jq '.categories[][] | select(.average_time_ns > 100000000)')
if [ ! -z "$SLOW_OPS" ]; then
  echo "Performance regression detected!"
  exit 1
fi
```

### Performance Comparison

#### ๐Ÿ“Š Simple Comparison Script

```bash
#!/bin/bash
# compare_benchmarks.sh

BASELINE="baseline.json"
CURRENT="current.json"
THRESHOLD=1.1  # 10% regression threshold

# Run current benchmark
./target/release/bench --format json > "$CURRENT"

# Compare with baseline (if exists)
if [ -f "$BASELINE" ]; then
  echo "๐Ÿ” Checking for performance changes..."

  # Extract and compare key metrics
  jq -r '.categories[][] | "\(.name) \(.average_time_ns)"' "$BASELINE" > baseline_times.txt
  jq -r '.categories[][] | "\(.name) \(.average_time_ns)"' "$CURRENT" > current_times.txt

  # Performance regression analysis
  python3 << 'EOF'
import json
import sys

with open('baseline.json') as f:
    baseline = json.load(f)
with open('current.json') as f:
    current = json.load(f)

threshold = 1.1
regressions = []

for category in baseline['categories']:
    for i, bench in enumerate(baseline['categories'][category]):
        current_bench = current['categories'][category][i]
        ratio = current_bench['average_time_ns'] / bench['average_time_ns']

        if ratio > threshold:
            regressions.append({
                'name': bench['name'],
                'baseline': bench['average_time_formatted'],
                'current': current_bench['average_time_formatted'],
                'ratio': f"{ratio:.2f}x"
            })

if regressions:
    print("โš ๏ธ  Performance changes detected:")
    for reg in regressions:
        print(f"  {reg['name']}: {reg['baseline']} โ†’ {reg['current']} ({reg['ratio']})")
    sys.exit(1)
else:
    print("โœ… No significant performance changes")
EOF
else
  echo "๐Ÿ“ No baseline found, creating baseline from current run..."
  cp "$CURRENT" "$BASELINE"
fi
```

## ๐Ÿ”ง Development Guide

### Adding New Benchmarks

#### ๐Ÿ“ Step-by-Step Process

1. **๐ŸŽฏ Identify the Operation Category**

   ```rust
   // Choose the appropriate method in src/bin/bench.rs
   fn run_single_operation_benchmarks()     // Individual operations
   fn run_multiple_simple_benchmarks()     // Operation chains
   fn run_multiple_map_benchmarks()        // Map operations
   fn run_complex_benchmarks()             // Complex scenarios
   ```

2. **โœ๏ธ Follow the Naming Convention**

   ```rust
   // Pattern: "Category: descriptive_name"
   ("Single: operation_name", "{template}")
   ("Multi: operation1 + operation2", "{template}")
   ("Map: split + map(operation)", "{template}")
   ("Complex: detailed_description", "{template}")
   ```

3. **๐Ÿงช Create Valid Templates**

   ```rust
   // โœ… Good examples
   ("Single: upper", "{upper}"),
   ("Multi: split + sort + join", "{split:,:..|sort|join:,}"),
   ("Map: split + map(trim)", "{split:,:..|map:{trim}|join:,}"),

   // โŒ Avoid these patterns
   ("Single: split", "{split:,}"),  // Missing range/join
   ("Map: nested", "{split:,:..|map:{map:{upper}}}"),  // Nested maps not supported
   ```

4. **๐Ÿ” Test with Small Iterations**

   ```bash
   # Test new benchmarks first
   cargo run --bin bench -- --iterations 10
   ```

### Performance Considerations

#### โšก Basic Guidelines

| Consideration | Impact | Recommendation |
|---------------|--------|----------------|
| **Build Mode** | 3-10x performance difference | Use `--release` for better measurements |
| **Iteration Count** | Result stability | 1000+ for automation, 2000+ for comparison |
| **Data Size** | Timing consistency | Current 208-char dataset works well |
| **System Load** | Measurement variance | Run on quiet systems when possible |
| **Memory** | Allocation overhead | Consider memory usage for intensive operations |

#### ๐Ÿ—๏ธ Architecture Insights

```rust
// Performance-critical path in benchmark execution
fn benchmark_template(&self, name: &str, template_str: &str) -> BenchmarkResult {
    // 1. Template compilation (one-time cost)
    let template = Template::parse(template_str, None).unwrap();

    // 2. Hot loop (measured operations)
    for _ in 0..self.iterations {
        let start = Instant::now();
        let _ = template.format(&self.test_data).unwrap();  // Core measurement
        let duration = start.elapsed();
        times.push(duration);
    }

    // 3. Basic analysis (post-processing)
    BenchmarkResult::new(name.to_string(), times)
}
```

### Best Practices

#### โœ… Do's

1. **๐Ÿญ Use Release Builds for Better Measurements**

   ```bash
   # Development/testing
   cargo run --bin bench -- --iterations 100

   # More accurate benchmarks
   cargo build --release --bin bench
   ./target/release/bench --iterations 2000
   ```

2. **๐Ÿ“Š Choose Appropriate Iteration Counts**

   ```bash
   # Quick development feedback (30-60 seconds)
   --iterations 50

   # Automated scripts (2-5 minutes)
   --iterations 1000

   # Thorough analysis (5-15 minutes)
   --iterations 5000
   ```

3. **๐Ÿ” Validate Templates Before Adding**

   ```bash
   # Test individual templates
   cargo run --bin string-pipeline -- "{new_template}" "test_data"
   ```

4. **๐Ÿ“ˆ Monitor Trends, Not Just Absolutes**

   ```bash
   # Track performance over time
   git log --oneline | head -10 | while read commit; do
     git checkout $commit
     ./target/release/bench --format json >> performance_history.jsonl
   done
   ```

#### โŒ Don'ts

1. **๐Ÿšซ Don't Mix Debug and Release Results**

   ```bash
   # Wrong: Comparing different build modes
   cargo run --bin bench > debug_results.txt
   cargo run --release --bin bench > release_results.txt
   # These results are not comparable!
   ```

2. **๐Ÿšซ Don't Ignore System Conditions**

   ```bash
   # Wrong: Running during high system load
   # Make sure system is idle before benchmarking

   # Right: Check system load
   top -bn1 | grep "load average"
   ```

3. **๐Ÿšซ Don't Skip Outlier Analysis**

   ```bash
   # Wrong: Assuming outliers are always noise
   # High outlier counts may indicate:
   # - System interference
   # - Memory allocation issues
   # - Template complexity problems
   ```

## โš ๏ธ Troubleshooting

### Common Issues

#### ๐Ÿ› Build Problems

**Problem:** `error: failed to remove file benchmark.exe`

```bash
# Solution: Process is still running
taskkill /F /IM bench.exe  # Windows
killall bench             # Linux/macOS

# Wait a moment, then rebuild
cargo build --release --bin bench
```

**Problem:** `Parse error: Expected operation`

```bash
# Check template syntax
cargo run --bin string-pipeline -- "{your_template}" "test"

# Common fixes:
"{split:,}"          โ†’ "{split:,:..|join:,}"
"{map:{map:{upper}}}" โ†’ "{split:,:..|map:{upper}}"
```

#### โšก Performance Issues

**Problem:** Benchmarks taking too long

```bash
# Reduce iterations for development
cargo run --bin bench -- --iterations 100

# Check system resources
htop  # Linux/macOS
taskmgr  # Windows
```

**Problem:** Inconsistent results

```bash
# Possible causes and solutions:
# 1. System load โ†’ Run on idle system
# 2. Debug build โ†’ Use --release
# 3. Too few iterations โ†’ Increase --iterations
# 4. Background processes โ†’ Close unnecessary applications
```

#### ๐Ÿ“Š Data Analysis Issues

**Problem:** JSON parsing errors

```bash
# Validate JSON output
./target/release/bench --format json | jq '.'

# Check for truncated output
./target/release/bench --format json > results.json
jq '.' results.json  # Should not error
```

**Problem:** Unexpected performance patterns

```bash
# Debug with template analysis
cargo run --bin string-pipeline -- "{!your_template}" "test_data"

# Profile memory usage
valgrind --tool=massif ./target/release/bench --iterations 100
```

> ๐Ÿ’ก **Need More Help?**
>
> ๐Ÿ” **Template Issues**: Check the [Template System Documentation]template-system.md for syntax help
>
> ๐Ÿ› **Debug Mode**: Use `{!template}` syntax to see step-by-step execution
>
> ๐Ÿ“Š **Performance Analysis**: Consider using `cargo flamegraph` for detailed profiling