@blinklabs/dingo 0.46.4 → 0.81.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.
- package/README.md +69 -563
- package/npm/bin/dingo.js +37 -0
- package/npm/checksums.json +8 -0
- package/npm/install.js +211 -0
- package/npm/postinstall.js +21 -0
- package/package.json +23 -14
- package/.dockerignore +0 -9
- package/AGENTS.md +0 -52
- package/ARCHITECTURE.md +0 -1157
- package/CLAUDE.md +0 -38
- package/RELEASE_NOTES.md +0 -2076
- package/benchmark_results.md +0 -130
- package/benchmark_results_bp_pi.md +0 -50
- package/benchmark_results_targeted.md +0 -102
- package/devmode.sh +0 -37
- package/dingo.yaml.example +0 -376
- package/docker-compose.yml +0 -51
- package/docs/dashboards/README.md +0 -188
- package/docs/dashboards/alerts.yaml +0 -29
- package/docs/dashboards/prometheus.yaml +0 -16
- package/docs/dashboards/provisioning.yaml +0 -14
- package/generate_benchmarks.sh +0 -588
- package/generate_bp_pi_report.sh +0 -359
package/generate_benchmarks.sh
DELETED
|
@@ -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!"
|