Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

\\t'/\\\\t}\"\n s=\"${s//

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

\\r'/}\"\n s=\"${s//

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

\\n'/\\\\n}\"\n printf '%s' \"$s\"\n}\n\n# Print human-readable output: stdout in text mode, stderr in JSON mode.\nlog() {\n if $JSON_OUTPUT; then\n echo \"$@\" >&2\n else\n echo \"$@\"\n fi\n}\n\nCOUNT=5\nBASELINE=\"\"\nSAVE=\"\"\nFILTER=\".\"\nPACKAGE=\"\"\nJSON_OUTPUT=false\nBENCHMEM=true\nFORCE=false\nLIMIT=0\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n -h|--help) usage; exit 0 ;;\n -v|--version) echo \"$SCRIPT_NAME v$VERSION\"; exit 0 ;;\n -n|--count) COUNT=\"${2:?error: --count requires a number}\"; shift 2 ;;\n -b|--baseline) BASELINE=\"${2:?error: --baseline requires a file path}\"; shift 2 ;;\n -s|--save) SAVE=\"${2:?error: --save requires a file path}\"; shift 2 ;;\n -f|--filter) FILTER=\"${2:?error: --filter requires a regex}\"; shift 2 ;;\n --json) JSON_OUTPUT=true; shift ;;\n --benchmem) BENCHMEM=true; shift ;;\n --no-benchmem) BENCHMEM=false; shift ;;\n --force) FORCE=true; shift ;;\n --limit) LIMIT=\"${2:?error: --limit requires a number}\"; shift 2 ;;\n -*) echo \"error: unknown option: $1\" >&2; usage >&2; exit 2 ;;\n *) PACKAGE=\"$1\"; shift ;;\n esac\ndone\n\nPACKAGE=\"${PACKAGE:-./...}\"\n\nif ! command -v go &>/dev/null; then\n echo \"error: 'go' command not found in PATH\" >&2\n exit 2\nfi\n\nif ! [[ \"$COUNT\" =~ ^[1-9][0-9]*$ ]]; then\n echo \"error: --count must be a positive integer, got: $COUNT\" >&2\n exit 2\nfi\n\nif ! [[ \"$LIMIT\" =~ ^[0-9]+$ ]]; then\n echo \"error: --limit must be a non-negative integer, got: $LIMIT\" >&2\n exit 2\nfi\n\nif [[ -n \"$BASELINE\" && ! -f \"$BASELINE\" ]]; then\n echo \"error: baseline file not found: $BASELINE\" >&2\n exit 2\nfi\n\nif [[ -n \"$SAVE\" && -f \"$SAVE\" ]] && ! $FORCE; then\n echo \"error: save target already exists: $SAVE (use --force to overwrite)\" >&2\n exit 2\nfi\n\nHAS_BENCHSTAT=false\nif command -v benchstat &>/dev/null; then\n HAS_BENCHSTAT=true\nfi\n\nBENCH_ARGS=(-bench \"$FILTER\" -count \"$COUNT\" -run '^

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

)\nif $BENCHMEM; then\n BENCH_ARGS+=(-benchmem)\nfi\n\nTMPFILE=$(mktemp \"${TMPDIR:-/tmp}/bench-XXXXXX.txt\")\ntrap 'rm -f \"$TMPFILE\"' EXIT\n\nlog \"Running benchmarks: go test ${BENCH_ARGS[*]} $PACKAGE\"\nlog \"Iterations: $COUNT\"\nlog \"\"\n\nGO_EXIT=0\nif $JSON_OUTPUT; then\n go test \"${BENCH_ARGS[@]}\" \"$PACKAGE\" 2>&1 | tee \"$TMPFILE\" >&2 || GO_EXIT=$?\nelse\n go test \"${BENCH_ARGS[@]}\" \"$PACKAGE\" 2>&1 | tee \"$TMPFILE\" || GO_EXIT=$?\nfi\n\nBENCH_COUNT=$(grep -cE '^Benchmark' \"$TMPFILE\" || true)\n\nTRUNCATED=false\nif [[ $LIMIT -gt 0 && $BENCH_COUNT -gt $LIMIT ]]; then\n TRUNCATED=true\nfi\n\nif ! $JSON_OUTPUT && $TRUNCATED; then\n log \"\"\n log \"Note: $BENCH_COUNT benchmark results found, showing first $LIMIT (--limit $LIMIT)\"\nfi\n\nif [[ -n \"$SAVE\" ]]; then\n cp \"$TMPFILE\" \"$SAVE\"\n log \"\"\n log \"Results saved to: $SAVE\"\nfi\n\nif [[ -n \"$BASELINE\" ]]; then\n log \"\"\n log \"=== Comparison with baseline: $BASELINE ===\"\n log \"\"\n if $HAS_BENCHSTAT; then\n if $JSON_OUTPUT; then\n benchstat \"$BASELINE\" \"$TMPFILE\" >&2 || true\n else\n benchstat \"$BASELINE\" \"$TMPFILE\" || true\n fi\n else\n log \"note: install benchstat for statistical comparison:\"\n log \" go install golang.org/x/perf/cmd/benchstat@latest\"\n log \"\"\n log \"--- Baseline ---\"\n if $JSON_OUTPUT; then\n grep -E '^Benchmark' \"$BASELINE\" >&2 || true\n else\n grep -E '^Benchmark' \"$BASELINE\" || true\n fi\n log \"\"\n log \"--- Current ---\"\n if $JSON_OUTPUT; then\n grep -E '^Benchmark' \"$TMPFILE\" >&2 || true\n else\n grep -E '^Benchmark' \"$TMPFILE\" || true\n fi\n fi\nfi\n\nFINAL_EXIT=0\nif [[ $GO_EXIT -ne 0 ]]; then\n FINAL_EXIT=1\n if ! $JSON_OUTPUT; then\n log \"\"\n log \"error: go test exited with code $GO_EXIT\"\n fi\nelif [[ $BENCH_COUNT -eq 0 ]]; then\n FINAL_EXIT=1\n if ! $JSON_OUTPUT; then\n log \"\"\n log \"error: no benchmarks found matching filter: $FILTER\"\n fi\nfi\n\nif $JSON_OUTPUT; then\n BENCH_OUTPUT=$(\u003c\"$TMPFILE\")\n if $TRUNCATED; then\n limited=\"\"\n bench_seen=0\n while IFS= read -r line; do\n if [[ \"$line\" =~ ^Benchmark ]]; then\n bench_seen=$((bench_seen + 1))\n if [[ $bench_seen -le $LIMIT ]]; then\n limited+=\"$line\"

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

\\n'\n fi\n else\n limited+=\"$line\"

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…

\\n'\n fi\n done \u003c \"$TMPFILE\"\n BENCH_OUTPUT=\"$limited\"\n fi\n\n escaped_package=$(json_escape \"$PACKAGE\")\n escaped_filter=$(json_escape \"$FILTER\")\n escaped_baseline=$(json_escape \"$BASELINE\")\n escaped_save=$(json_escape \"$SAVE\")\n escaped_output=$(json_escape \"$BENCH_OUTPUT\")\n\n printf '{\"count\":%d,' \"$COUNT\"\n printf '\"package\":\"%s\",' \"$escaped_package\"\n printf '\"filter\":\"%s\",' \"$escaped_filter\"\n printf '\"benchmarks_found\":%d,' \"$BENCH_COUNT\"\n printf '\"baseline\":\"%s\",' \"$escaped_baseline\"\n printf '\"save\":\"%s\",' \"$escaped_save\"\n printf '\"exit_code\":%d,' \"$GO_EXIT\"\n printf '\"output\":\"%s\"' \"$escaped_output\"\n if $TRUNCATED; then\n printf ',\"truncated\":true'\n fi\n printf '}\\n'\nfi\n\nexit $FINAL_EXIT\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":7269,"content_sha256":"8ae74ecb862f3b3e83bbdce719e8c4486e9c156829ae31266775ce7fe5e0ba7d"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Go Performance Patterns","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Available Scripts","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/bench-compare.sh","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run ","type":"text"},{"text":"bash scripts/bench-compare.sh --help","type":"text","marks":[{"type":"code_inline"}]},{"text":" for options.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Performance-specific guidelines apply only to the ","type":"text"},{"text":"hot path","type":"text","marks":[{"type":"strong"}]},{"text":". Don't prematurely optimize—focus these patterns where they matter most.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prefer strconv over fmt","type":"text"}]},{"type":"paragraph","content":[{"text":"When converting primitives to/from strings, ","type":"text"},{"text":"strconv","type":"text","marks":[{"type":"code_inline"}]},{"text":" is faster than ","type":"text"},{"text":"fmt","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"go"},"content":[{"text":"s := strconv.Itoa(rand.Int()) // ~2x faster than fmt.Sprint()","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Approach","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Speed","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Allocations","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"fmt.Sprint","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"143 ns/op","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2 allocs/op","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"strconv.Itoa","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"64.2 ns/op","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 allocs/op","type":"text"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/STRING-OPTIMIZATION.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/STRING-OPTIMIZATION.md","title":null}}]},{"text":" when choosing between strconv and fmt for type conversions, or for the full conversion table.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Avoid Repeated String-to-Byte Conversions","type":"text"}]},{"type":"paragraph","content":[{"text":"Convert a fixed string to ","type":"text"},{"text":"[]byte","type":"text","marks":[{"type":"code_inline"}]},{"text":" once outside the loop:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"go"},"content":[{"text":"data := []byte(\"Hello world\")\nfor i := 0; i \u003c b.N; i++ {\n w.Write(data) // ~7x faster than []byte(\"...\") each iteration\n}","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/STRING-OPTIMIZATION.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/STRING-OPTIMIZATION.md","title":null}}]},{"text":" when optimizing repeated byte conversions in hot loops.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prefer Specifying Container Capacity","type":"text"}]},{"type":"paragraph","content":[{"text":"Specify container capacity where possible to allocate memory up front. This minimizes subsequent allocations from copying and resizing as elements are added.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Map Capacity Hints","type":"text"}]},{"type":"paragraph","content":[{"text":"Provide capacity hints when initializing maps with ","type":"text"},{"text":"make()","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"go"},"content":[{"text":"m := make(map[string]os.DirEntry, len(files))","type":"text"}]},{"type":"paragraph","content":[{"text":"Note","type":"text","marks":[{"type":"strong"}]},{"text":": Unlike slices, map capacity hints do not guarantee complete preemptive allocation—they approximate the number of hashmap buckets required.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Slice Capacity","type":"text"}]},{"type":"paragraph","content":[{"text":"Provide capacity hints when initializing slices with ","type":"text"},{"text":"make()","type":"text","marks":[{"type":"code_inline"}]},{"text":", particularly when appending:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"go"},"content":[{"text":"data := make([]int, 0, size)","type":"text"}]},{"type":"paragraph","content":[{"text":"Unlike maps, slice capacity is ","type":"text"},{"text":"not a hint","type":"text","marks":[{"type":"strong"}]},{"text":"—the compiler allocates exactly that much memory. Subsequent ","type":"text"},{"text":"append()","type":"text","marks":[{"type":"code_inline"}]},{"text":" operations incur zero allocations until capacity is reached.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Approach","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Time (100M iterations)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No capacity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2.48s","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"With capacity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0.21s","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"The capacity version is ","type":"text"},{"text":"~12x faster","type":"text","marks":[{"type":"strong"}]},{"text":" due to zero reallocations during append.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pass Values","type":"text"}]},{"type":"paragraph","content":[{"text":"Don't pass pointers as function arguments just to save a few bytes. If a function refers to its argument ","type":"text"},{"text":"x","type":"text","marks":[{"type":"code_inline"}]},{"text":" only as ","type":"text"},{"text":"*x","type":"text","marks":[{"type":"code_inline"}]},{"text":" throughout, then the argument shouldn't be a pointer.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"go"},"content":[{"text":"func process(s string) { // not *string — strings are small fixed-size headers\n fmt.Println(s)\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Common pass-by-value types","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"string","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"io.Reader","type":"text","marks":[{"type":"code_inline"}]},{"text":", small structs.","type":"text"}]},{"type":"paragraph","content":[{"text":"Exceptions","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Large structs where copying is expensive","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Small structs that might grow in the future","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"String Concatenation","type":"text"}]},{"type":"paragraph","content":[{"text":"Choose the right strategy based on complexity:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Method","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best For","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Few strings, simple concat","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"fmt.Sprintf","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Formatted output with mixed types","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"strings.Builder","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Loop/piecemeal construction","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"strings.Join","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Joining a slice","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Backtick literal","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Constant multi-line text","type":"text"}]}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/STRING-OPTIMIZATION.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/STRING-OPTIMIZATION.md","title":null}}]},{"text":" when choosing a string concatenation strategy, using strings.Builder in loops, or deciding between fmt.Sprintf and manual concatenation.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Benchmarking and Profiling","type":"text"}]},{"type":"paragraph","content":[{"text":"Always measure before and after optimizing. Use Go's built-in benchmark framework and profiling tools.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"go test -bench=. -benchmem -count=10 ./...","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"references/BENCHMARKS.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/BENCHMARKS.md","title":null}}]},{"text":" when writing benchmarks, comparing results with benchstat, profiling with pprof, or interpreting benchmark output.","type":"text"}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Validation","type":"text","marks":[{"type":"strong"}]},{"text":": After applying optimizations, run ","type":"text"},{"text":"bash scripts/bench-compare.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" to measure the actual impact. Only keep optimizations with measurable improvement.","type":"text"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bad","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Good","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Improvement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Int to string","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"fmt.Sprint(n)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"strconv.Itoa(n)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~2x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated ","type":"text"},{"text":"[]byte","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"[]byte(\"str\")","type":"text","marks":[{"type":"code_inline"}]},{"text":" in loop","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Convert once outside","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~7x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Map initialization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"make(map[K]V)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"make(map[K]V, size)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fewer allocs","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slice initialization","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"make([]T, 0)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"make([]T, 0, cap)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~12x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Small fixed-size args","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"*string","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"*io.Reader","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"string","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"io.Reader","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No indirection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Simple string join","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s1 + \" \" + s2","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"(already good)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"+","type":"text","marks":[{"type":"code_inline"}]},{"text":" for few strings","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Loop string build","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Repeated ","type":"text"},{"text":"+=","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"strings.Builder","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"O(n) vs O(n²)","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Data structures","type":"text","marks":[{"type":"strong"}]},{"text":": See ","type":"text"},{"text":"go-data-structures","type":"text","marks":[{"type":"link","attrs":{"href":"../go-data-structures/SKILL.md","title":null}}]},{"text":" when choosing between slices, maps, and arrays, or understanding allocation semantics","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Declaration patterns","type":"text","marks":[{"type":"strong"}]},{"text":": See ","type":"text"},{"text":"go-declarations","type":"text","marks":[{"type":"link","attrs":{"href":"../go-declarations/SKILL.md","title":null}}]},{"text":" when using ","type":"text"},{"text":"make","type":"text","marks":[{"type":"code_inline"}]},{"text":" with capacity hints or initializing maps and slices","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concurrency","type":"text","marks":[{"type":"strong"}]},{"text":": See ","type":"text"},{"text":"go-concurrency","type":"text","marks":[{"type":"link","attrs":{"href":"../go-concurrency/SKILL.md","title":null}}]},{"text":" when parallelizing work across goroutines or using sync.Pool for buffer reuse","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Style principles","type":"text","marks":[{"type":"strong"}]},{"text":": See ","type":"text"},{"text":"go-style-core","type":"text","marks":[{"type":"link","attrs":{"href":"../go-style-core/SKILL.md","title":null}}]},{"text":" when deciding whether an optimization is worth the readability cost","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"go-performance","author":"@skillopedia","source":{"stars":102,"repo_name":"golang-skills","origin_url":"https://github.com/cxuu/golang-skills/blob/HEAD/skills/go-performance/SKILL.md","repo_owner":"cxuu","body_sha256":"5f3374854c5c373eed78536e299ebae5561def4bcee4cb174694daa8a1571812","cluster_key":"3f695314a1d2c480ca9eac50e7e53eb367ed5075052b6ee22316b3838e77b537","clean_bundle":{"format":"clean-skill-bundle-v1","source":"cxuu/golang-skills/skills/go-performance/SKILL.md","attachments":[{"id":"bd239806-d3ff-576b-9095-599fe4a895da","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bd239806-d3ff-576b-9095-599fe4a895da/attachment.md","path":"references/BENCHMARKS.md","size":6444,"sha256":"a9d1c1b5f62a584b2e38d76817bb1b902cba6800e675d10116859e63cc712ea8","contentType":"text/markdown; charset=utf-8"},{"id":"186b2f7e-8d8d-5884-a624-5d63b3729562","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/186b2f7e-8d8d-5884-a624-5d63b3729562/attachment.md","path":"references/STRING-OPTIMIZATION.md","size":3147,"sha256":"f452045515a232e601660f5c1b1b4cf024e61f76bf8d5cb19fb230ead432a966","contentType":"text/markdown; charset=utf-8"},{"id":"d5b16f0b-25d6-56a8-9ad8-10ece1a93ce0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d5b16f0b-25d6-56a8-9ad8-10ece1a93ce0/attachment.sh","path":"scripts/bench-compare.sh","size":7269,"sha256":"8ae74ecb862f3b3e83bbdce719e8c4486e9c156829ae31266775ce7fe5e0ba7d","contentType":"application/x-sh; charset=utf-8"}],"bundle_sha256":"4a90581f678ba415bec0b97da48a29c276d6f7d34ce4d1426101f251f4e9f3f5","attachment_count":3,"text_attachments":3,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/go-performance/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"web-development","metadata":{"sources":"Uber Style Guide, Google Style Guide, Go Wiki CodeReviewComments"},"import_tag":"clean-skills-v1","description":"Use when optimizing Go code, investigating slow performance, or writing performance-critical sections. Also use when a user mentions slow Go code, string concatenation in loops, or asks about benchmarking, even if the user doesn't explicitly mention performance patterns. Does not cover concurrent performance patterns (see go-concurrency).","allowed-tools":"Bash(bash:*)"}},"renderedAt":1782986997002}

Go Performance Patterns Available Scripts - — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run for options. 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, is faster than : | Approach | Speed | Allocations | |----------|-------|-------------| | | 143 ns/op | 2 allocs/op | | | 64.2 ns/op | 1 allocs/op | Read references/STRING-OPTIMIZATION.md when choosing between…