@blinklabs/dingo 0.46.4 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,588 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # Copyright 2025 Blink Labs Software
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- # Script to generate benchmark results for Dingo ledger and database with historical tracking
18
- # Usage: ./generate_benchmarks.sh [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]
19
- # --write: Write results to file (default: display only)
20
-
21
- WRITE_TO_FILE=false
22
- OUTPUT_FILE="benchmark_results.md"
23
- BENCH_REGEX="."
24
- BENCH_PACKAGES="./..."
25
- REPORT_TITLE="Dingo Ledger & Database Benchmark Results"
26
- REPORT_SCOPE=""
27
- REPORT_DATA_SOURCE="Real Cardano preview testnet data (40k+ blocks, slots 0-863,996)"
28
- BENCH_TIME=""
29
-
30
- # Parse arguments
31
- while [[ $# -gt 0 ]]; do
32
- case $1 in
33
- --write)
34
- WRITE_TO_FILE=true
35
- shift
36
- ;;
37
- --bench)
38
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --bench requires a value"; exit 1; }
39
- BENCH_REGEX="$2"
40
- shift 2
41
- ;;
42
- --packages)
43
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --packages requires a value"; exit 1; }
44
- BENCH_PACKAGES="$2"
45
- shift 2
46
- ;;
47
- --benchtime)
48
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --benchtime requires a value"; exit 1; }
49
- BENCH_TIME="$2"
50
- shift 2
51
- ;;
52
- --title)
53
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --title requires a value"; exit 1; }
54
- REPORT_TITLE="$2"
55
- shift 2
56
- ;;
57
- --scope)
58
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --scope requires a value"; exit 1; }
59
- REPORT_SCOPE="$2"
60
- shift 2
61
- ;;
62
- --data-source)
63
- [[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --data-source requires a value"; exit 1; }
64
- REPORT_DATA_SOURCE="$2"
65
- shift 2
66
- ;;
67
- -*)
68
- echo "Unknown option: $1"
69
- echo "Usage: $0 [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]"
70
- exit 1
71
- ;;
72
- *)
73
- # First non-option argument is the output file
74
- if [[ -z "$OUTPUT_FILE_SET" ]]; then
75
- OUTPUT_FILE="$1"
76
- OUTPUT_FILE_SET=true
77
- else
78
- echo "Too many arguments. Usage: $0 [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]"
79
- exit 1
80
- fi
81
- shift
82
- ;;
83
- esac
84
- done
85
-
86
- DATE=$(date +"%B %d, %Y")
87
-
88
- # Initialize environment information for benchmark report
89
- GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//')
90
- OS=$(uname -s)
91
- ARCH=$(uname -m)
92
- CPU_CORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo "unknown")
93
-
94
- echo "Running Dingo benchmarks..."
95
- echo "==============================="
96
-
97
- # Run benchmarks with progress output first
98
- echo "Executing benchmarks (this may take a few minutes)..."
99
-
100
- # Enable pipefail to catch go test failures in the pipeline
101
- set -o pipefail
102
-
103
- # Run go test once, capture output while showing progress
104
- IFS=',' read -r -a BENCHMARK_PACKAGE_ARGS <<< "$BENCH_PACKAGES"
105
- BENCHMARK_ARGS=(-bench="$BENCH_REGEX" -benchmem -run=^$)
106
- if [[ -n "$BENCH_TIME" ]]; then
107
- BENCHMARK_ARGS+=("-benchtime=$BENCH_TIME")
108
- fi
109
- BENCHMARK_OUTPUT=$(go test "${BENCHMARK_ARGS[@]}" "${BENCHMARK_PACKAGE_ARGS[@]}" 2>&1)
110
- GO_TEST_EXIT_CODE=$?
111
-
112
- # Show progress by parsing benchmark names from output
113
- echo "$BENCHMARK_OUTPUT" | grep "^Benchmark" | sed 's/Benchmark//' | sed 's/-[0-9]*$//' | while read -r name rest; do
114
- echo "Running: $name"
115
- done
116
-
117
- # Check if go test succeeded
118
- if [[ $GO_TEST_EXIT_CODE -ne 0 ]]; then
119
- echo "Benchmark run failed!"
120
- exit 1
121
- fi
122
-
123
- # Count benchmarks
124
- BENCHMARK_COUNT=$(echo "$BENCHMARK_OUTPUT" | grep "^Benchmark" | wc -l)
125
-
126
- echo "Found $BENCHMARK_COUNT benchmarks across all packages"
127
- echo ""
128
-
129
- # Function to parse benchmark line
130
- parse_benchmark() {
131
- local line="$1"
132
- local name
133
- name=$(echo "$line" | awk '{print $1}' | sed 's/Benchmark//' | sed 's/-[0-9]*$//')
134
- local iterations
135
- iterations=$(echo "$line" | awk '{print $2}' | sed 's/,//g')
136
- local time_val
137
- time_val=$(echo "$line" | awk '{print $3}')
138
- local time_unit
139
- time_unit=$(echo "$line" | awk '{print $4}')
140
-
141
- local extra_metrics=""
142
- local mem_op="N/A"
143
- local allocs_op="N/A"
144
- local idx=5
145
- local token_count
146
- token_count=$(echo "$line" | awk '{print NF}')
147
-
148
- while [[ $idx -le $token_count ]]; do
149
- local metric_val
150
- metric_val=$(echo "$line" | awk -v i="$idx" '{print $i}')
151
- local metric_unit
152
- metric_unit=$(echo "$line" | awk -v i="$((idx + 1))" '{print $i}')
153
-
154
- if [[ -z "$metric_val" || -z "$metric_unit" ]]; then
155
- break
156
- fi
157
-
158
- case "$metric_unit" in
159
- "B/op")
160
- if [[ "$metric_val" =~ ^[0-9]+$ && $metric_val -gt 1000 ]]; then
161
- mem_kb=$((metric_val / 1000))
162
- mem_op="${mem_kb}KB"
163
- else
164
- mem_op="${metric_val}B"
165
- fi
166
- ;;
167
- "allocs/op")
168
- allocs_op="$metric_val"
169
- ;;
170
- *)
171
- if [[ -n "$extra_metrics" ]]; then
172
- extra_metrics="${extra_metrics}, "
173
- fi
174
- extra_metrics="${extra_metrics}${metric_val} ${metric_unit}"
175
- ;;
176
- esac
177
-
178
- idx=$((idx + 2))
179
- done
180
-
181
- # Format time
182
- if [[ "$time_unit" == "ns/op" ]]; then
183
- time_op="${time_val}ns"
184
- elif [[ "$time_unit" == "μs/op" ]] || [[ "$time_unit" == "µs/op" ]]; then
185
- time_op="${time_val}μs"
186
- elif [[ "$time_unit" == "ms/op" ]]; then
187
- time_op="${time_val}ms"
188
- elif [[ "$time_unit" == "s/op" ]]; then
189
- time_op="${time_val}s"
190
- else
191
- time_op="${time_val}${time_unit}"
192
- fi
193
-
194
- if [[ -z "$extra_metrics" ]]; then
195
- extra_metrics="-"
196
- fi
197
-
198
- # Format benchmark name nicely
199
- formatted_name=$(echo "$name" | sed 's/\([A-Z]\)/ \1/g' | sed 's/^ //' | sed 's/NoData$/ (No Data)/' | sed 's/RealData$/ (Real Data)/')
200
-
201
- echo "$formatted_name|$iterations|$time_op|$extra_metrics|$mem_op|$allocs_op"
202
- }
203
-
204
- # Parse current results into temporary file, tracking current package
205
- # go test outputs "pkg: <import-path>" before each package's benchmarks
206
- CURRENT_RESULTS_FILE=$(mktemp "${TMPDIR:-/tmp}/dingo_bench_XXXXXX")
207
- current_pkg=""
208
- while IFS= read -r line; do
209
- if [[ "$line" =~ ^pkg:[[:space:]]+(.+)$ ]]; then
210
- current_pkg="${BASH_REMATCH[1]}"
211
- elif [[ "$line" =~ ^ok[[:space:]] || "$line" =~ ^FAIL[[:space:]] ]]; then
212
- current_pkg=""
213
- elif [[ "$line" =~ ^Benchmark ]]; then
214
- parsed=$(parse_benchmark "$line")
215
- name=$(echo "$parsed" | cut -d'|' -f1)
216
- data=$(echo "$parsed" | cut -d'|' -f2-)
217
- if [[ -n "$current_pkg" ]]; then
218
- pkg_short=$(basename "$current_pkg")
219
- echo "${pkg_short}:${name}|$data" >> "$CURRENT_RESULTS_FILE"
220
- else
221
- echo "$name|$data" >> "$CURRENT_RESULTS_FILE"
222
- fi
223
- fi
224
- done <<< "$BENCHMARK_OUTPUT"
225
-
226
- # Deduplicate benchmark names (composite key: package+benchmark)
227
- sort -t'|' -k1,1 -u "$CURRENT_RESULTS_FILE" > "$CURRENT_RESULTS_FILE.tmp" && mv "$CURRENT_RESULTS_FILE.tmp" "$CURRENT_RESULTS_FILE"
228
-
229
- # Display current results summary
230
- echo "Current Benchmark Summary"
231
- echo "-------------------------"
232
- echo "Most iterations (>100k iters):"
233
- sort -t'|' -k2,2nr "$CURRENT_RESULTS_FILE" | head -3 | while IFS='|' read -r name iterations _; do
234
- echo " - $name: ${iterations} iterations"
235
- done
236
-
237
- echo ""
238
- echo "Fewest iterations (<1k iters):"
239
- awk -F'|' '$2 < 1000 {print $1 "|" $2}' "$CURRENT_RESULTS_FILE" | while IFS='|' read -r name iterations; do
240
- echo " - $name: ${iterations} iterations"
241
- done
242
-
243
- echo ""
244
- echo "Memory usage:"
245
- awk -F'|' '
246
- function mem_bytes(v) {
247
- if (v ~ /KB$/) {
248
- sub(/KB$/, "", v)
249
- return v + 0
250
- }
251
- if (v ~ /B$/) {
252
- sub(/B$/, "", v)
253
- return (v + 0) / 1000
254
- }
255
- return -1
256
- }
257
- {
258
- print mem_bytes($5) "|" $1 "|" $5
259
- }
260
- ' "$CURRENT_RESULTS_FILE" | sort -t'|' -k1,1nr | head -3 | while IFS='|' read -r _ name mem; do
261
- echo " - $name: ${mem} per op"
262
- done
263
-
264
- # Read previous results if file exists and we're comparing
265
- PREVIOUS_RESULTS_FILE=$(mktemp "${TMPDIR:-/tmp}/dingo_bench_XXXXXX")
266
- trap 'rm -f "$CURRENT_RESULTS_FILE" "$PREVIOUS_RESULTS_FILE"' EXIT
267
- previous_date=""
268
- MAJOR_CHANGES=false
269
-
270
- if [[ -f "$OUTPUT_FILE" && "$WRITE_TO_FILE" == "true" ]]; then
271
- echo ""
272
- echo "Comparing with previous results..."
273
- # Extract previous date
274
- previous_date=$(grep "\*\*Date\*\*:" "$OUTPUT_FILE" | head -1 | sed 's/.*\*\*Date\*\*: //' || echo "")
275
-
276
- # Parse previous benchmark table
277
- in_table=false
278
- while IFS= read -r line; do
279
- # Stop parsing at performance changes or historical results sections
280
- if [[ "$line" == "## Performance Changes" || "$line" == "## Historical Results" ]]; then
281
- break
282
- fi
283
- if [[ "$line" == "| Benchmark | Operations/sec | Time/op | Memory/op | Allocs/op |" ||
284
- "$line" == "| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |" ]]; then
285
- in_table=true
286
- continue
287
- fi
288
- # Skip separator rows (e.g. |---|---|...)
289
- if [[ "$line" =~ ^\|[-[:space:]\|]+\|$ ]]; then
290
- continue
291
- fi
292
- if [[ "$in_table" == true && "$line" =~ ^\|.*\|.*\|.*\|.*\|.*\|$ ]]; then
293
- # Parse table row
294
- benchmark=$(echo "$line" | sed 's/^| //' | cut -d'|' -f1 | sed 's/ *$//')
295
- # Count fields to detect 5-column vs 6-column format
296
- field_count=$(echo "$line" | awk -F'|' '{print NF - 2}')
297
-
298
- if [[ "$field_count" -le 5 ]]; then
299
- # Old 5-column format: Benchmark | Operations/sec | Time/op | Memory/op | Allocs/op
300
- iterations="-"
301
- time_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f3 | sed 's/ //g')
302
- extra_metrics=$(echo "$line" | sed 's/^| //' | cut -d'|' -f2 | sed 's/^ *//' | sed 's/ *$//')
303
- mem_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f4 | sed 's/ //g')
304
- allocs_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f5 | sed 's/ //g')
305
- else
306
- # Current 6-column format
307
- iterations=$(echo "$line" | sed 's/^| //' | cut -d'|' -f2 | sed 's/ //g' | sed 's/,//g')
308
- time_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f3 | sed 's/ //g')
309
- extra_metrics=$(echo "$line" | sed 's/^| //' | cut -d'|' -f4 | sed 's/^ *//' | sed 's/ *$//')
310
- mem_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f5 | sed 's/ //g')
311
- allocs_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f6 | sed 's/ //g')
312
- fi
313
-
314
- if [[ -n "$benchmark" && -n "$time_op" ]]; then
315
- echo "$benchmark|$iterations|$time_op|$extra_metrics|$mem_op|$allocs_op" >> "$PREVIOUS_RESULTS_FILE"
316
- fi
317
- fi
318
- if [[ "$in_table" == true && "$line" == "" ]]; then
319
- in_table=false
320
- fi
321
- done < "$OUTPUT_FILE"
322
- fi
323
-
324
- # Deduplicate previous benchmark names
325
- sort -t'|' -k1,1 -u "$PREVIOUS_RESULTS_FILE" > "$PREVIOUS_RESULTS_FILE.tmp" && mv "$PREVIOUS_RESULTS_FILE.tmp" "$PREVIOUS_RESULTS_FILE"
326
-
327
- # Helper functions to get data from temp files
328
- get_current_data() {
329
- local benchmark="$1"
330
- awk -F'|' '$1 == "'"$benchmark"'" {print substr($0, index($0, "|")+1)}' "$CURRENT_RESULTS_FILE"
331
- }
332
-
333
- get_previous_data() {
334
- local benchmark="$1"
335
- awk -F'|' '$1 == "'"$benchmark"'" {print substr($0, index($0, "|")+1)}' "$PREVIOUS_RESULTS_FILE"
336
- }
337
-
338
- list_current_benchmarks() {
339
- awk -F'|' '!seen[$1]++ {print $1}' "$CURRENT_RESULTS_FILE"
340
- }
341
-
342
- list_previous_benchmarks() {
343
- awk -F'|' '!seen[$1]++ {print $1}' "$PREVIOUS_RESULTS_FILE"
344
- }
345
-
346
- # Generate performance comparison if we have previous results
347
- if [[ -n "$previous_date" && "$WRITE_TO_FILE" == "true" ]]; then
348
- # Track changes
349
- faster_benchmarks=""
350
- slower_benchmarks=""
351
- new_benchmarks=""
352
- removed_benchmarks=""
353
-
354
- # Compare results
355
- while IFS= read -r benchmark; do
356
- if [[ -n "$(get_previous_data "$benchmark")" ]]; then
357
- # Benchmark exists in both
358
- current_data=$(get_current_data "$benchmark")
359
- previous_data=$(get_previous_data "$benchmark")
360
-
361
- current_iters=$(echo "$current_data" | cut -d'|' -f1)
362
- previous_iters=$(echo "$previous_data" | cut -d'|' -f1)
363
-
364
- if [[ "$current_iters" =~ ^[0-9]+$ && "$previous_iters" =~ ^[0-9]+$ && $previous_iters -gt 0 ]]; then
365
- change=$(( (current_iters - previous_iters) * 100 / previous_iters ))
366
- if [[ $change -gt 10 ]]; then
367
- faster_benchmarks="$faster_benchmarks
368
- $benchmark (+${change}%)"
369
- elif [[ $change -lt -10 ]]; then
370
- change_abs=$(( (previous_iters - current_iters) * 100 / previous_iters ))
371
- slower_benchmarks="$slower_benchmarks
372
- $benchmark (-${change_abs}%)"
373
- MAJOR_CHANGES=true
374
- fi
375
- fi
376
- else
377
- new_benchmarks="$new_benchmarks
378
- $benchmark"
379
- fi
380
- done < <(list_current_benchmarks)
381
-
382
- # Check for removed benchmarks
383
- while IFS= read -r benchmark; do
384
- if [[ -z "$(get_current_data "$benchmark")" ]]; then
385
- removed_benchmarks="$removed_benchmarks
386
- $benchmark"
387
- fi
388
- done < <(list_previous_benchmarks)
389
-
390
- # Count items (remove empty lines and count)
391
- faster_count=$(echo "$faster_benchmarks" | sed '/^$/d' | wc -l)
392
- slower_count=$(echo "$slower_benchmarks" | sed '/^$/d' | wc -l)
393
- new_count=$(echo "$new_benchmarks" | sed '/^$/d' | wc -l)
394
- removed_count=$(echo "$removed_benchmarks" | sed '/^$/d' | wc -l)
395
-
396
- echo ""
397
- echo "Performance Changes Summary:"
398
- echo " Faster: $faster_count | Slower: $slower_count | New: $new_count | Removed: $removed_count"
399
-
400
- # Report changes if any improvements, regressions, or new benchmarks detected
401
- if [[ $faster_count -gt 0 || $slower_count -gt 0 || $new_count -gt 0 ]]; then
402
- MAJOR_CHANGES=true
403
- fi
404
- fi
405
-
406
- # Decide whether to write to file
407
- if [[ "$WRITE_TO_FILE" == "true" ]]; then
408
- echo ""
409
- if [[ "$MAJOR_CHANGES" == "true" ]]; then
410
- echo "Writing results to file (major changes detected)..."
411
- elif [[ -z "$previous_date" ]]; then
412
- echo "Writing results to file (first benchmark run)..."
413
- else
414
- echo "Writing results to file (--write flag used)..."
415
- fi
416
-
417
- # Generate performance comparison for file
418
- generate_comparison() {
419
- echo "## Performance Changes"
420
- echo ""
421
- if [[ -z "$previous_date" ]]; then
422
- echo "No previous results found. This is the first benchmark run."
423
- echo ""
424
- return
425
- fi
426
-
427
- echo "Changes since **$previous_date**:"
428
- echo ""
429
-
430
- # Track changes
431
- faster_benchmarks=""
432
- slower_benchmarks=""
433
- new_benchmarks=""
434
- removed_benchmarks=""
435
-
436
- # Compare results
437
- while IFS= read -r benchmark; do
438
- if [[ -n "$(get_previous_data "$benchmark")" ]]; then
439
- # Benchmark exists in both
440
- current_data=$(get_current_data "$benchmark")
441
- previous_data=$(get_previous_data "$benchmark")
442
-
443
- current_iters=$(echo "$current_data" | cut -d'|' -f1)
444
- previous_iters=$(echo "$previous_data" | cut -d'|' -f1)
445
-
446
- if [[ "$current_iters" =~ ^[0-9]+$ && "$previous_iters" =~ ^[0-9]+$ && $previous_iters -gt 0 ]]; then
447
- if [[ $current_iters -gt $previous_iters ]]; then
448
- change=$(( (current_iters - previous_iters) * 100 / previous_iters ))
449
- faster_benchmarks="$faster_benchmarks
450
- $benchmark (+${change}%)"
451
- elif [[ $current_iters -lt $previous_iters ]]; then
452
- change=$(( (previous_iters - current_iters) * 100 / previous_iters ))
453
- slower_benchmarks="$slower_benchmarks
454
- $benchmark (-${change}%)"
455
- fi
456
- fi
457
- else
458
- new_benchmarks="$new_benchmarks
459
- $benchmark"
460
- fi
461
- done < <(list_current_benchmarks)
462
-
463
- # Check for removed benchmarks
464
- while IFS= read -r benchmark; do
465
- if [[ -z "$(get_current_data "$benchmark")" ]]; then
466
- removed_benchmarks="$removed_benchmarks
467
- $benchmark"
468
- fi
469
- done < <(list_previous_benchmarks)
470
-
471
- # Count items
472
- faster_count=$(echo "$faster_benchmarks" | sed '/^$/d' | wc -l)
473
- slower_count=$(echo "$slower_benchmarks" | sed '/^$/d' | wc -l)
474
- new_count=$(echo "$new_benchmarks" | sed '/^$/d' | wc -l)
475
- removed_count=$(echo "$removed_benchmarks" | sed '/^$/d' | wc -l)
476
-
477
- echo "### Summary"
478
- echo "- **Faster benchmarks**: $faster_count"
479
- echo "- **Slower benchmarks**: $slower_count"
480
- echo "- **New benchmarks**: $new_count"
481
- echo "- **Removed benchmarks**: $removed_count"
482
- echo ""
483
-
484
- if [[ $faster_count -gt 0 ]]; then
485
- echo "### Top Improvements"
486
- echo "$faster_benchmarks" | grep "^." | sort -t'(' -k2 -nr | head -5 | sed 's/^/- /'
487
- echo ""
488
- fi
489
-
490
- if [[ $slower_count -gt 0 ]]; then
491
- echo "### Performance Regressions"
492
- echo "$slower_benchmarks" | grep "^." | sort -t'(' -k2 -nr | head -5 | sed 's/^/- /'
493
- echo ""
494
- fi
495
-
496
- if [[ $new_count -gt 0 ]]; then
497
- echo "### New Benchmarks Added"
498
- echo "$new_benchmarks" | grep "^." | sed 's/^/- /'
499
- echo ""
500
- fi
501
-
502
- if [[ $removed_count -gt 0 ]]; then
503
- echo "### Benchmarks Removed"
504
- echo "$removed_benchmarks" | grep "^." | sed 's/^/- /'
505
- echo ""
506
- fi
507
- }
508
-
509
- # Create the markdown file
510
- cat > "$OUTPUT_FILE.tmp" << EOF
511
- # $REPORT_TITLE
512
-
513
- ## Latest Results
514
-
515
- ### Test Environment
516
- - **Date**: $DATE
517
- - **Go Version**: $GO_VERSION
518
- - **OS**: $OS
519
- - **Architecture**: $ARCH
520
- - **CPU Cores**: $CPU_CORES
521
- - **Data Source**: $REPORT_DATA_SOURCE
522
- EOF
523
-
524
- if [[ -n "$REPORT_SCOPE" ]]; then
525
- cat >> "$OUTPUT_FILE.tmp" << EOF
526
- - **Scope**: $REPORT_SCOPE
527
- EOF
528
- fi
529
-
530
- cat >> "$OUTPUT_FILE.tmp" << EOF
531
-
532
- ### Benchmark Results
533
-
534
- All benchmarks run with \`-benchmem\` flag. Iterations are Go benchmark iteration counts; benchmark-specific throughput metrics (for example \`blocks/sec\`) are reported separately.
535
-
536
- | Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |
537
- |-----------|------------|---------|---------------|-----------|-----------|
538
- EOF
539
-
540
- # Add current results to table
541
- while IFS= read -r benchmark; do
542
- data=$(get_current_data "$benchmark")
543
- iterations=$(echo "$data" | cut -d'|' -f1)
544
- time_op=$(echo "$data" | cut -d'|' -f2)
545
- extra_metrics=$(echo "$data" | cut -d'|' -f3)
546
- mem_op=$(echo "$data" | cut -d'|' -f4)
547
- allocs_op=$(echo "$data" | cut -d'|' -f5)
548
- echo "| $benchmark | $iterations | $time_op | $extra_metrics | $mem_op | $allocs_op |" >> "$OUTPUT_FILE.tmp"
549
- done < <(list_current_benchmarks)
550
-
551
- # Add comparison section
552
- echo "" >> "$OUTPUT_FILE.tmp"
553
- generate_comparison >> "$OUTPUT_FILE.tmp"
554
-
555
- # Add historical section if previous results exist
556
- if [[ -n "$previous_date" ]]; then
557
- echo "" >> "$OUTPUT_FILE.tmp"
558
- echo "## Historical Results" >> "$OUTPUT_FILE.tmp"
559
- echo "" >> "$OUTPUT_FILE.tmp"
560
- echo "### $previous_date" >> "$OUTPUT_FILE.tmp"
561
- echo "" >> "$OUTPUT_FILE.tmp"
562
- echo "| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |" >> "$OUTPUT_FILE.tmp"
563
- echo "|-----------|------------|---------|---------------|-----------|-----------|" >> "$OUTPUT_FILE.tmp"
564
-
565
- # Add previous results
566
- while IFS= read -r benchmark; do
567
- data=$(get_previous_data "$benchmark")
568
- iterations=$(echo "$data" | cut -d'|' -f1)
569
- time_op=$(echo "$data" | cut -d'|' -f2)
570
- extra_metrics=$(echo "$data" | cut -d'|' -f3)
571
- mem_op=$(echo "$data" | cut -d'|' -f4)
572
- allocs_op=$(echo "$data" | cut -d'|' -f5)
573
- echo "| $benchmark | $iterations | $time_op | $extra_metrics | $mem_op | $allocs_op |" >> "$OUTPUT_FILE.tmp"
574
- done < <(list_previous_benchmarks)
575
- fi
576
-
577
- # Move temp file to final location
578
- mv "$OUTPUT_FILE.tmp" "$OUTPUT_FILE"
579
-
580
- echo "Benchmark results saved to $OUTPUT_FILE"
581
- else
582
- echo ""
583
- echo "To save these results to file, run: ./generate_benchmarks.sh --write"
584
- echo "Results are only saved when major performance changes are detected."
585
- fi
586
-
587
- echo ""
588
- echo "Benchmark run complete!"