
Go Performance
- 939 installs
- 137 repo stars
- Updated June 20, 2026
- cxuu/golang-skills
Go Performance is a Claude Code skill that teaches developers to write, run, and interpret Go benchmarks measuring CPU time and memory usage before shipping backend Go services.
About
Go Performance is a Claude Code skill for Go backend engineers who need disciplined benchmark methodology instead of guesswork profiling. It documents how to write Benchmark functions in _test.go files using testing.B, loop with b.N, prevent compiler dead-code elimination, and call b.ResetTimer after setup. The skill covers comparing strconv versus fmt approaches, reading ns/op and allocation lines, and using benchstat or benchcmp workflows to judge regressions. Developers reach for Go Performance when optimizing hot paths, validating micro-optimizations, or establishing a repeatable benchmark suite before release.
- Teaches correct use of testing.B with b.N loop control and result assignment to prevent compiler optimization
- Explains b.ResetTimer(), b.ReportAllocs(), and sub-benchmarks with b.Run()
- Provides exact go test commands including -benchmem and -count=10 for statistical significance
- Covers both writing benchmarks in _test.go files and running them with memory and allocation tracking
- Delivers reusable benchmark methodology that improves Go performance measurement accuracy
Go Performance by the numbers
- 939 all-time installs (skills.sh)
- +39 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #546 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cxuu/golang-skills --skill go-performanceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 939 |
|---|---|
| repo stars | ★ 137 |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 20, 2026 |
| Repository | cxuu/golang-skills ↗ |
How do you benchmark Go code correctly?
Write, run, and interpret Go benchmarks that measure performance and memory usage before shipping backend code.
Who is it for?
Go backend engineers optimizing hot paths who need reproducible testing.B benchmarks and clear before-and-after performance reads.
Skip if: Teams not using Go or developers who only need distributed tracing and production APM without local micro-benchmarks.
When should I use this skill?
The user asks to benchmark Go code, write Benchmark functions, measure allocations, compare strconv vs fmt performance, or interpret go test -bench results.
What you get
Go _test.go benchmark functions, benchstat comparisons, and interpreted ns/op and memory allocation reports.
- benchmark functions
- bench comparison reports
Files
Go Performance Patterns
Resource Routing
scripts/bench-compare.sh- Run when comparing benchmark results, saving baselines, or producing JSON benchmark metadata.references/BENCHMARKS.md- Read when writing benchmarks, using benchstat, or profiling with pprof.references/STRING-OPTIMIZATION.md- Read when optimizing string conversion, concatenation, or byte/string boundaries.
Performance-specific guidelines apply only to the hot path. Don't prematurely optimize—focus these patterns where they matter most.
---
Prefer strconv over fmt
When converting primitives to/from strings, strconv is faster than fmt:
s := strconv.Itoa(rand.Int()) // ~2x faster than fmt.Sprint()| Approach | Speed | Allocations |
|---|---|---|
fmt.Sprint | 143 ns/op | 2 allocs/op |
strconv.Itoa | 64.2 ns/op | 1 allocs/op |
---
Avoid Repeated String-to-Byte Conversions
Convert a fixed string to []byte once outside the loop:
data := []byte("Hello world")
for b.Loop() { // Go 1.24+; use b.N loops only for older Go
w.Write(data) // ~7x faster than []byte("...") each iteration
}---
Prefer Specifying Container Capacity
Specify container capacity where possible to allocate memory up front. This minimizes subsequent allocations from copying and resizing as elements are added.
Map Capacity Hints
Provide capacity hints when initializing maps with make():
m := make(map[string]os.DirEntry, len(files))Note: Unlike slices, map capacity hints do not guarantee complete preemptive allocation—they approximate the number of hashmap buckets required.
Slice Capacity
Provide capacity hints when initializing slices with make(), particularly when appending:
data := make([]int, 0, size)Unlike maps, slice capacity is not a hint—the compiler allocates exactly that much memory. Subsequent append() operations incur zero allocations until capacity is reached.
| Approach | Time (100M iterations) |
|---|---|
| No capacity | 2.48s |
| With capacity | 0.21s |
The capacity version is ~12x faster due to zero reallocations during append.
---
Pass Values
Don't pass pointers as function arguments just to save a few bytes. If a function refers to its argument x only as *x throughout, then the argument shouldn't be a pointer.
func process(s string) { // not *string — strings are small fixed-size headers
fmt.Println(s)
}Common pass-by-value types: string, io.Reader, small structs.
Exceptions:
- Large structs where copying is expensive
- Small structs that might grow in the future
---
String Concatenation
Choose the right strategy based on complexity:
| Method | Best For |
|---|---|
+ | Few strings, simple concat |
fmt.Sprintf | Formatted output with mixed types |
strings.Builder | Loop/piecemeal construction |
strings.Join | Joining a slice |
| Backtick literal | Constant multi-line text |
---
Benchmarking and Profiling
Always measure before and after optimizing. Use Go's built-in benchmark framework and profiling tools.
go test -bench=. -benchmem -count=10 ./...Validation: After applying optimizations, run bash scripts/bench-compare.sh to measure the actual impact. Only keep optimizations with measurable improvement.---
Quick Reference
| Pattern | Bad | Good | Improvement |
|---|---|---|---|
| Int to string | fmt.Sprint(n) | strconv.Itoa(n) | ~2x faster |
Repeated []byte | []byte("str") in loop | Convert once outside | ~7x faster |
| Map initialization | make(map[K]V) | make(map[K]V, size) | Fewer allocs |
| Slice initialization | make([]T, 0) | make([]T, 0, cap) | ~12x faster |
| Small fixed-size args | *string, *io.Reader | string, io.Reader | No indirection |
| Simple string join | s1 + " " + s2 | (already good) | Use + for few strings |
| Loop string build | Repeated += | strings.Builder | O(n) vs O(n²) |
---
Related Skills
- Data structures: See go-data-structures when choosing between slices, maps, and arrays, or understanding allocation semantics
- Declaration patterns: See go-declarations when using
makewith capacity hints or initializing maps and slices - Concurrency: See go-concurrency when parallelizing work across goroutines or using sync.Pool for buffer reuse
- Style principles: See go-style-core when deciding whether an optimization is worth the readability cost
Benchmark Methodology
Contents
- Writing Benchmarks
- Running Benchmarks
- Interpreting Results
- Using benchstat for Comparison
- Benchmark Examples from Performance Patterns
- Profiling with pprof
- Common Mistakes
Writing Benchmarks
Go benchmarks use the testing.B type and live in _test.go files. Function names must start with Benchmark. On Go 1.24+, prefer b.Loop().
func BenchmarkStrconv(b *testing.B) {
for b.Loop() {
s := strconv.Itoa(rand.Int())
_ = s
}
}
func BenchmarkFmtSprint(b *testing.B) {
for b.Loop() {
s := fmt.Sprint(rand.Int())
_ = s
}
}Key rules:
- Use
b.Loop()on Go 1.24+; usefor i := 0; i < b.N; i++only when
maintaining older Go versions
- Assign results to a variable (or
_) to prevent the compiler from
optimizing away the call
- Use
b.ResetTimer()after expensive setup that shouldn't be measured - Use
b.ReportAllocs()or the-benchmemflag for allocation tracking
Sub-benchmarks
func BenchmarkConvert(b *testing.B) {
for _, size := range []int{10, 100, 1000} {
b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
data := make([]byte, size)
b.ResetTimer()
for b.Loop() {
_ = string(data)
}
})
}
}---
Running Benchmarks
# Run all benchmarks in a package
go test -bench=. ./...
# Run specific benchmark with memory stats
go test -bench=BenchmarkStrconv -benchmem ./...
# Run with count for statistical significance
go test -bench=. -benchmem -count=10 ./...The -benchmem flag reports allocations per operation. The -count flag runs each benchmark N times for statistical significance.
---
Interpreting Results
BenchmarkStrconv-8 18705042 64.2 ns/op 16 B/op 1 allocs/op
BenchmarkFmtSprint-8 8249536 143.0 ns/op 16 B/op 2 allocs/op| Field | Meaning |
|---|---|
-8 | GOMAXPROCS |
18705042 | Number of iterations |
64.2 ns/op | Time per operation |
16 B/op | Bytes allocated per operation |
1 allocs/op | Heap allocations per operation |
---
Using benchstat for Comparison
benchstat compares benchmark results statistically. Install it and save benchmark output to files:
# Install benchstat
go install golang.org/x/perf/cmd/benchstat@latest
# Run benchmarks and save results
go test -bench=. -benchmem -count=10 ./... > old.txt
# Make changes, then run again
go test -bench=. -benchmem -count=10 ./... > new.txt
# Compare results
benchstat old.txt new.txtInterpreting benchstat Output
name old time/op new time/op delta
Strconv-8 64.2ns ± 2% 61.8ns ± 1% -3.74% (p=0.001 n=10+10)- delta: Percentage change (negative = faster)
- p-value: Statistical significance (p < 0.05 is significant)
- n: Number of valid samples used
Tips:
- Always use
-count=10or higher for reliable results - A small p-value confirms the change is real, not noise
- If benchstat shows
~(tilde), the difference is not statistically
significant
---
Benchmark Examples from Performance Patterns
strconv vs fmt
| Approach | Speed | Allocations |
|---|---|---|
fmt.Sprint | 143 ns/op | 2 allocs/op |
strconv.Itoa | 64.2 ns/op | 1 allocs/op |
Repeated Byte Conversions
func BenchmarkRepeatedConversion(b *testing.B) {
var buf bytes.Buffer
for b.Loop() {
buf.Write([]byte("Hello world"))
}
}
func BenchmarkSingleConversion(b *testing.B) {
var buf bytes.Buffer
data := []byte("Hello world")
for b.Loop() {
buf.Write(data)
}
}| Approach | Speed |
|---|---|
| Repeated conversion | 22.2 ns/op |
| Single conversion | 3.25 ns/op |
Slice Capacity
func BenchmarkNoCapacity(b *testing.B) {
for b.Loop() {
data := make([]int, 0)
for k := 0; k < 1000; k++ {
data = append(data, k)
}
}
}
func BenchmarkWithCapacity(b *testing.B) {
for b.Loop() {
data := make([]int, 0, 1000)
for k := 0; k < 1000; k++ {
data = append(data, k)
}
}
}| Approach | Time (100M iterations) |
|---|---|
| No capacity | 2.48s |
| With capacity | 0.21s |
---
Profiling with pprof
Use pprof to identify bottlenecks before optimizing. Benchmarks measure improvement; pprof finds where to improve.
CPU Profiling
# Generate a CPU profile from benchmarks
go test -bench=BenchmarkHotPath -cpuprofile=cpu.prof ./...
# Analyze with pprof
go tool pprof cpu.profCommon pprof commands:
(pprof) top10 # Top 10 functions by CPU time
(pprof) list funcName # Annotated source for a function
(pprof) web # Interactive graph in browserMemory Profiling
# Generate a memory profile
go test -bench=BenchmarkHotPath -memprofile=mem.prof ./...
# Analyze allocations
go tool pprof -alloc_space mem.profHTTP Profiling for Running Services
import _ "net/http/pprof"
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// ... application code ...
}Access profiles at http://localhost:6060/debug/pprof/.
Profiling Workflow
1. Benchmark the suspected hot path 2. Profile with pprof to confirm where time is spent 3. Optimize using patterns from this skill 4. Re-benchmark to verify improvement with benchstat 5. Re-profile to check for new bottlenecks
---
Common Mistakes
Ignoring the benchmark loop
The testing framework adjusts iteration counts to get stable timing. Using a fixed iteration count produces meaningless results:
// Bad: Ignores the benchmark loop, so the framework can't calibrate
func BenchmarkFixed(b *testing.B) {
for i := 0; i < 1000; i++ {
doWork()
}
}
// Good: Use b.Loop on Go 1.24+
func BenchmarkCorrect(b *testing.B) {
for b.Loop() {
doWork()
}
}Not preventing compiler elision
If the result of a function call is unused, the compiler may optimize the call away entirely. Assign results to a package-level variable:
// Bad: Compiler may optimize away the call
func BenchmarkElided(b *testing.B) {
for b.Loop() {
expensiveFunc()
}
}
// Good: Assign to package-level var to prevent elision
var benchResult int
func BenchmarkKept(b *testing.B) {
var r int
for b.Loop() {
r = expensiveFunc()
}
benchResult = r
}String Optimization Patterns
strconv vs fmt
When converting primitives to/from strings, strconv is faster than fmt because fmt uses reflection and handles arbitrary types.
Benchmark snippets use b.Loop(), available in Go 1.24 and newer. For older Go versions, use for i := 0; i < b.N; i++.
Bad:
for b.Loop() {
s := fmt.Sprint(rand.Int())
}Good:
for b.Loop() {
s := strconv.Itoa(rand.Int())
}Benchmark comparison:
| Approach | Speed | Allocations |
|---|---|---|
fmt.Sprint | 143 ns/op | 2 allocs/op |
strconv.Itoa | 64.2 ns/op | 1 allocs/op |
Common conversions:
| Task | fmt | strconv |
|---|---|---|
| Int → string | fmt.Sprint(n) | strconv.Itoa(n) |
| Int64 → string | fmt.Sprint(n) | strconv.FormatInt(n, 10) |
| Float → string | fmt.Sprint(f) | strconv.FormatFloat(f, 'f', -1, 64) |
| String → int | — | strconv.Atoi(s) |
| Bool → string | fmt.Sprint(b) | strconv.FormatBool(b) |
---
Repeated String-to-Byte Conversions
Do not create byte slices from a fixed string repeatedly. Instead, perform the conversion once and capture the result.
Bad:
for b.Loop() {
w.Write([]byte("Hello world"))
}Good:
data := []byte("Hello world")
for b.Loop() {
w.Write(data)
}Benchmark comparison:
| Approach | Speed |
|---|---|
| Repeated conversion | 22.2 ns/op |
| Single conversion | 3.25 ns/op |
The good version is ~7x faster because it avoids allocating a new byte slice on each iteration.
---
String Concatenation
Choose the right string building strategy based on complexity.
Use + for Simple Cases
key := "projectid: " + pThe + operator is efficient for a small, fixed number of strings. The compiler can often optimize adjacent string literals.
Use fmt.Sprintf for Formatting
// Good: clear formatting
str := fmt.Sprintf("%s [%s:%d]-> %s", src, qos, mtu, dst)
// Bad: + with manual conversions
str := src.String() + " [" + qos.String() + ":" + strconv.Itoa(mtu) + "]-> " + dst.String()When writing to an io.Writer, use fmt.Fprintf directly instead of building a temporary string with fmt.Sprintf.
Use strings.Builder for Piecemeal Construction
strings.Builder takes amortized linear time, whereas repeated + or fmt.Sprintf take quadratic time when building a large string:
b := new(strings.Builder)
for i, d := range digitsOfPi {
fmt.Fprintf(b, "the %d digit of pi is: %d\n", i, d)
}
str := b.String()Use Backticks for Constant Multi-line Strings
// Good: raw string literal
usage := `Usage:
custom_tool [args]`
// Bad: concatenation with escape sequences
usage := "" +
"Usage:\n" +
"\n" +
"custom_tool [args]"Strategy Summary
| Method | Best For | Performance |
|---|---|---|
+ | Few strings, simple concat | O(n) for small n |
fmt.Sprintf | Formatted output | Slower, but clearer |
strings.Builder | Loop/piecemeal construction | Amortized O(n) |
strings.Join | Joining a slice | O(n) |
| Backtick literal | Constant multi-line text | Zero cost |
#!/usr/bin/env bash
set -euo pipefail
VERSION="1.1.0"
SCRIPT_NAME="$(basename "$0")"
usage() {
cat <<EOF
$SCRIPT_NAME v$VERSION — Run Go benchmarks with optional comparison
USAGE
bash $SCRIPT_NAME [options] [package]
DESCRIPTION
Wrapper around 'go test -bench' that runs benchmarks multiple times and
optionally compares results against a saved baseline using benchstat.
Results can be saved to a file for future comparison. If benchstat is
installed and a baseline is provided, a statistical comparison is shown.
EXIT CODES
0 Benchmarks ran successfully
1 go test failed (compilation error, test failure, no benchmarks found)
2 Usage error (missing arguments, bad flags, file exists without --force)
OPTIONS
-h, --help Show this help message
-v, --version Show version
-n, --count N Number of benchmark iterations (default: 5)
-b, --baseline FILE Compare results against this baseline file
-s, --save FILE Save benchmark results to this file
-f, --filter REGEX Benchmark filter regex (default: ".")
--json Output metadata as JSON (human output goes to stderr)
--benchmem Include memory allocation stats (default: on)
--no-benchmem Disable memory allocation stats
--force Allow --save to overwrite existing files
--limit N Max benchmark result lines to include (default: 0 = all)
ARGUMENTS
package Go package to benchmark (default: ./...)
EXAMPLES
bash $SCRIPT_NAME
bash $SCRIPT_NAME -n 10 ./pkg/parser
bash $SCRIPT_NAME --save baseline.txt ./...
bash $SCRIPT_NAME --baseline baseline.txt --save current.txt ./...
bash $SCRIPT_NAME --filter BenchmarkSort -n 3
bash $SCRIPT_NAME --json --limit 5 ./...
bash $SCRIPT_NAME --save results.txt --force ./...
EOF
}
json_escape() {
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//$'\t'/\\t}"
s="${s//$'\r'/}"
s="${s//$'\n'/\\n}"
printf '%s' "$s"
}
# Print human-readable output: stdout in text mode, stderr in JSON mode.
log() {
if $JSON_OUTPUT; then
echo "$@" >&2
else
echo "$@"
fi
}
COUNT=5
BASELINE=""
SAVE=""
FILTER="."
PACKAGE=""
JSON_OUTPUT=false
BENCHMEM=true
FORCE=false
LIMIT=0
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
-v|--version) echo "$SCRIPT_NAME v$VERSION"; exit 0 ;;
-n|--count) COUNT="${2:?error: --count requires a number}"; shift 2 ;;
-b|--baseline) BASELINE="${2:?error: --baseline requires a file path}"; shift 2 ;;
-s|--save) SAVE="${2:?error: --save requires a file path}"; shift 2 ;;
-f|--filter) FILTER="${2:?error: --filter requires a regex}"; shift 2 ;;
--json) JSON_OUTPUT=true; shift ;;
--benchmem) BENCHMEM=true; shift ;;
--no-benchmem) BENCHMEM=false; shift ;;
--force) FORCE=true; shift ;;
--limit) LIMIT="${2:?error: --limit requires a number}"; shift 2 ;;
-*) echo "error: unknown option: $1" >&2; usage >&2; exit 2 ;;
*) PACKAGE="$1"; shift ;;
esac
done
PACKAGE="${PACKAGE:-./...}"
if ! command -v go &>/dev/null; then
echo "error: 'go' command not found in PATH" >&2
exit 2
fi
if ! [[ "$COUNT" =~ ^[1-9][0-9]*$ ]]; then
echo "error: --count must be a positive integer, got: $COUNT" >&2
exit 2
fi
if ! [[ "$LIMIT" =~ ^[0-9]+$ ]]; then
echo "error: --limit must be a non-negative integer, got: $LIMIT" >&2
exit 2
fi
if [[ -n "$BASELINE" && ! -f "$BASELINE" ]]; then
echo "error: baseline file not found: $BASELINE" >&2
exit 2
fi
if [[ -n "$SAVE" && -f "$SAVE" ]] && ! $FORCE; then
echo "error: save target already exists: $SAVE (use --force to overwrite)" >&2
exit 2
fi
HAS_BENCHSTAT=false
if command -v benchstat &>/dev/null; then
HAS_BENCHSTAT=true
fi
BENCH_ARGS=(-bench "$FILTER" -count "$COUNT" -run '^$')
if $BENCHMEM; then
BENCH_ARGS+=(-benchmem)
fi
TMPFILE=$(mktemp "${TMPDIR:-/tmp}/bench-XXXXXX.txt")
trap 'rm -f "$TMPFILE"' EXIT
log "Running benchmarks: go test ${BENCH_ARGS[*]} $PACKAGE"
log "Iterations: $COUNT"
log ""
GO_EXIT=0
if $JSON_OUTPUT; then
go test "${BENCH_ARGS[@]}" "$PACKAGE" 2>&1 | tee "$TMPFILE" >&2 || GO_EXIT=$?
else
go test "${BENCH_ARGS[@]}" "$PACKAGE" 2>&1 | tee "$TMPFILE" || GO_EXIT=$?
fi
BENCH_COUNT=$(grep -cE '^Benchmark' "$TMPFILE" || true)
TRUNCATED=false
if [[ $LIMIT -gt 0 && $BENCH_COUNT -gt $LIMIT ]]; then
TRUNCATED=true
fi
if ! $JSON_OUTPUT && $TRUNCATED; then
log ""
log "Note: $BENCH_COUNT benchmark results found, showing first $LIMIT (--limit $LIMIT)"
fi
if [[ -n "$SAVE" ]]; then
cp "$TMPFILE" "$SAVE"
log ""
log "Results saved to: $SAVE"
fi
if [[ -n "$BASELINE" ]]; then
log ""
log "=== Comparison with baseline: $BASELINE ==="
log ""
if $HAS_BENCHSTAT; then
if $JSON_OUTPUT; then
benchstat "$BASELINE" "$TMPFILE" >&2 || true
else
benchstat "$BASELINE" "$TMPFILE" || true
fi
else
log "note: install benchstat for statistical comparison:"
log " go install golang.org/x/perf/cmd/benchstat@latest"
log ""
log "--- Baseline ---"
if $JSON_OUTPUT; then
grep -E '^Benchmark' "$BASELINE" >&2 || true
else
grep -E '^Benchmark' "$BASELINE" || true
fi
log ""
log "--- Current ---"
if $JSON_OUTPUT; then
grep -E '^Benchmark' "$TMPFILE" >&2 || true
else
grep -E '^Benchmark' "$TMPFILE" || true
fi
fi
fi
FINAL_EXIT=0
if [[ $GO_EXIT -ne 0 ]]; then
FINAL_EXIT=1
if ! $JSON_OUTPUT; then
log ""
log "error: go test exited with code $GO_EXIT"
fi
elif [[ $BENCH_COUNT -eq 0 ]]; then
FINAL_EXIT=1
if ! $JSON_OUTPUT; then
log ""
log "error: no benchmarks found matching filter: $FILTER"
fi
fi
if $JSON_OUTPUT; then
BENCH_OUTPUT=$(<"$TMPFILE")
if $TRUNCATED; then
limited=""
bench_seen=0
while IFS= read -r line; do
if [[ "$line" =~ ^Benchmark ]]; then
bench_seen=$((bench_seen + 1))
if [[ $bench_seen -le $LIMIT ]]; then
limited+="$line"$'\n'
fi
else
limited+="$line"$'\n'
fi
done < "$TMPFILE"
BENCH_OUTPUT="$limited"
fi
escaped_package=$(json_escape "$PACKAGE")
escaped_filter=$(json_escape "$FILTER")
escaped_baseline=$(json_escape "$BASELINE")
escaped_save=$(json_escape "$SAVE")
escaped_output=$(json_escape "$BENCH_OUTPUT")
printf '{"count":%d,' "$COUNT"
printf '"package":"%s",' "$escaped_package"
printf '"filter":"%s",' "$escaped_filter"
printf '"benchmarks_found":%d,' "$BENCH_COUNT"
printf '"baseline":"%s",' "$escaped_baseline"
printf '"save":"%s",' "$escaped_save"
printf '"exit_code":%d,' "$GO_EXIT"
printf '"output":"%s"' "$escaped_output"
if $TRUNCATED; then
printf ',"truncated":true'
fi
printf '}\n'
fi
exit $FINAL_EXIT
Related skills
How it compares
Pick Go Performance over generic profiling guides when the task is authoring and reading testing.B micro-benchmarks in Go _test.go files.
FAQ
How does Go Performance teach benchmark writing?
Go Performance teaches Go developers to place Benchmark-prefixed functions in _test.go files, loop with testing.B's b.N, assign outputs to avoid dead-code elimination, and call b.ResetTimer after setup so measurements cover only the hot path.
When should Go developers use the Go Performance skill?
Go developers should use Go Performance before shipping backend changes when they need reproducible CPU and memory benchmarks, want to compare implementations like strconv versus fmt, or must interpret ns/op and allocation lines for regression decisions.
Is Go Performance safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.