{"id":"b016de6e-177a-4d60-a19a-5ba4c8d1ea9c","shortId":"VcHVBk","kind":"skill","title":"go-performance","tagline":"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","description":"# Go Performance Patterns\n\n## Available Scripts\n\n- **`scripts/bench-compare.sh`** — Runs Go benchmarks N times with optional baseline comparison via benchstat. Supports saving results for future comparison. Run `bash scripts/bench-compare.sh --help` for options.\n\nPerformance-specific guidelines apply only to the **hot path**. Don't prematurely optimize—focus these patterns where they matter most.\n\n---\n\n## Prefer strconv over fmt\n\nWhen converting primitives to/from strings, `strconv` is faster than `fmt`:\n\n```go\ns := strconv.Itoa(rand.Int()) // ~2x faster than fmt.Sprint()\n```\n\n| Approach | Speed | Allocations |\n|----------|-------|-------------|\n| `fmt.Sprint` | 143 ns/op | 2 allocs/op |\n| `strconv.Itoa` | 64.2 ns/op | 1 allocs/op |\n\n> Read [references/STRING-OPTIMIZATION.md](references/STRING-OPTIMIZATION.md) when choosing between strconv and fmt for type conversions, or for the full conversion table.\n\n---\n\n## Avoid Repeated String-to-Byte Conversions\n\nConvert a fixed string to `[]byte` once outside the loop:\n\n```go\ndata := []byte(\"Hello world\")\nfor i := 0; i < b.N; i++ {\n    w.Write(data) // ~7x faster than []byte(\"...\") each iteration\n}\n```\n\n> Read [references/STRING-OPTIMIZATION.md](references/STRING-OPTIMIZATION.md) when optimizing repeated byte conversions in hot loops.\n\n---\n\n## Prefer Specifying Container Capacity\n\nSpecify container capacity where possible to allocate memory up front. This minimizes subsequent allocations from copying and resizing as elements are added.\n\n### Map Capacity Hints\n\nProvide capacity hints when initializing maps with `make()`:\n\n```go\nm := make(map[string]os.DirEntry, len(files))\n```\n\n**Note**: Unlike slices, map capacity hints do not guarantee complete preemptive allocation—they approximate the number of hashmap buckets required.\n\n### Slice Capacity\n\nProvide capacity hints when initializing slices with `make()`, particularly when appending:\n\n```go\ndata := make([]int, 0, size)\n```\n\nUnlike maps, slice capacity is **not a hint**—the compiler allocates exactly that much memory. Subsequent `append()` operations incur zero allocations until capacity is reached.\n\n| Approach | Time (100M iterations) |\n|----------|------------------------|\n| No capacity | 2.48s |\n| With capacity | 0.21s |\n\nThe capacity version is **~12x faster** due to zero reallocations during append.\n\n---\n\n## Pass Values\n\nDon'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.\n\n```go\nfunc process(s string) { // not *string — strings are small fixed-size headers\n    fmt.Println(s)\n}\n```\n\n**Common pass-by-value types**: `string`, `io.Reader`, small structs.\n\n**Exceptions**:\n- Large structs where copying is expensive\n- Small structs that might grow in the future\n\n---\n\n## String Concatenation\n\nChoose the right strategy based on complexity:\n\n| Method | Best For |\n|--------|----------|\n| `+` | Few strings, simple concat |\n| `fmt.Sprintf` | Formatted output with mixed types |\n| `strings.Builder` | Loop/piecemeal construction |\n| `strings.Join` | Joining a slice |\n| Backtick literal | Constant multi-line text |\n\n> Read [references/STRING-OPTIMIZATION.md](references/STRING-OPTIMIZATION.md) when choosing a string concatenation strategy, using strings.Builder in loops, or deciding between fmt.Sprintf and manual concatenation.\n\n---\n\n## Benchmarking and Profiling\n\nAlways measure before and after optimizing. Use Go's built-in benchmark framework and profiling tools.\n\n```bash\ngo test -bench=. -benchmem -count=10 ./...\n```\n\n> Read [references/BENCHMARKS.md](references/BENCHMARKS.md) when writing benchmarks, comparing results with benchstat, profiling with pprof, or interpreting benchmark output.\n\n> **Validation**: After applying optimizations, run `bash scripts/bench-compare.sh` to measure the actual impact. Only keep optimizations with measurable improvement.\n\n---\n\n## Quick Reference\n\n| Pattern | Bad | Good | Improvement |\n|---------|-----|------|-------------|\n| Int to string | `fmt.Sprint(n)` | `strconv.Itoa(n)` | ~2x faster |\n| Repeated `[]byte` | `[]byte(\"str\")` in loop | Convert once outside | ~7x faster |\n| Map initialization | `make(map[K]V)` | `make(map[K]V, size)` | Fewer allocs |\n| Slice initialization | `make([]T, 0)` | `make([]T, 0, cap)` | ~12x faster |\n| Small fixed-size args | `*string`, `*io.Reader` | `string`, `io.Reader` | No indirection |\n| Simple string join | `s1 + \" \" + s2` | (already good) | Use `+` for few strings |\n| Loop string build | Repeated `+=` | `strings.Builder` | O(n) vs O(n²) |\n\n---\n\n## Related Skills\n\n- **Data structures**: See [go-data-structures](../go-data-structures/SKILL.md) when choosing between slices, maps, and arrays, or understanding allocation semantics\n- **Declaration patterns**: See [go-declarations](../go-declarations/SKILL.md) when using `make` with capacity hints or initializing maps and slices\n- **Concurrency**: See [go-concurrency](../go-concurrency/SKILL.md) when parallelizing work across goroutines or using sync.Pool for buffer reuse\n- **Style principles**: See [go-style-core](../go-style-core/SKILL.md) when deciding whether an optimization is worth the readability cost","tags":["performance","golang","skills","cxuu","agent-skills","ai-agent","ai-assistant","claude","claude-code","codex","cursor","llm"],"capabilities":["skill","source-cxuu","skill-go-performance","topic-agent-skills","topic-ai-agent","topic-ai-assistant","topic-claude","topic-claude-code","topic-codex","topic-cursor","topic-golang","topic-llm"],"categories":["golang-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cxuu/golang-skills/go-performance","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cxuu/golang-skills","source_repo":"https://github.com/cxuu/golang-skills","install_from":"skills.sh"}},"qualityScore":"0.491","qualityRationale":"deterministic score 0.49 from registry signals: · indexed on github topic:agent-skills · 82 github stars · SKILL.md body (5,219 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T12:55:18.992Z","embedding":null,"createdAt":"2026-04-18T22:13:20.404Z","updatedAt":"2026-05-02T12:55:18.992Z","lastSeenAt":"2026-05-02T12:55:18.992Z","tsv":"'/go-concurrency/skill.md':650 '/go-data-structures/skill.md':615 '/go-declarations/skill.md':633 '/go-style-core/skill.md':669 '0':174,279,567,570 '0.21':316 '1':130 '10':488 '100m':308 '12x':322,572 '143':123 '2':125 '2.48':312 '2x':115,537 '64.2':128 '7x':180,548 'across':654 'actual':516 'ad':222 'alloc':121,207,214,253,291,301,562,625 'allocs/op':126,131 'alreadi':590 'also':18 'alway':465 'append':274,297,329 'appli':80,508 'approach':119,306 'approxim':255 'arg':578 'argument':338,351,359 'array':622 'ask':32 'avail':50 'avoid':150 'b.n':176 'backtick':435 'bad':527 'base':412 'baselin':60 'bash':71,482,511 'bench':485 'benchmark':34,55,462,477,494,504 'benchmem':486 'benchstat':63,498 'best':416 'bucket':260 'buffer':660 'build':598 'built':475 'built-in':474 'byte':155,162,169,183,192,344,540,541 'cap':571 'capac':200,203,224,227,246,263,265,284,303,311,315,319,638 'choos':136,408,446,617 'code':8,26 'common':381 'compar':495 'comparison':61,69 'compil':290 'complet':251 'complex':414 'concat':421 'concaten':28,407,449,461 'concurr':645,649 'constant':437 'construct':430 'contain':199,202 'convers':143,148,156,193 'convert':102,157,545 'copi':216,395 'core':668 'cost':679 'count':487 'critic':16 'data':168,179,276,608,613 'decid':456,671 'declar':627,632 'doesn':39 'due':324 'element':220 'even':35 'exact':292 'except':391 'expens':397 'explicit':41 'faster':108,116,181,323,538,549,573 'fewer':561 'file':241 'fix':159,376,576 'fixed-s':375,575 'fmt':100,110,140 'fmt.println':379 'fmt.sprint':118,122,533 'fmt.sprintf':422,458 'focus':90 'format':423 'framework':478 'front':210 'full':147 'func':366 'function':337,347 'futur':68,405 'go':2,7,25,47,54,111,167,234,275,365,472,483,612,631,648,666 'go-concurr':647 'go-data-structur':611 'go-declar':630 'go-perform':1 'go-style-cor':665 'good':528,591 'goroutin':655 'grow':402 'guarante':250 'guidelin':79 'hashmap':259 'header':378 'hello':170 'help':73 'hint':225,228,247,266,288,639 'hot':84,195 'impact':517 'improv':523,529 'incur':299 'indirect':584 'initi':230,268,551,564,641 'int':278,530 'interpret':503 'investig':9 'io.reader':388,580,582 'iter':185,309 'join':432,587 'k':554,558 'keep':519 'larg':392 'len':240 'line':440 'liter':436 'loop':30,166,196,454,544,596 'loop/piecemeal':429 'm':235 'make':233,236,271,277,552,556,565,568,636 'manual':460 'map':223,231,237,245,282,550,553,557,620,642 'matter':95 'measur':466,514,522 'memori':208,295 'mention':23,42 'method':415 'might':401 'minim':212 'mix':426 'much':294 'multi':439 'multi-lin':438 'n':56,534,536,602,605 'note':242 'ns/op':124,129 'number':257 'o':601,604 'oper':298 'optim':6,89,190,470,509,520,674 'option':59,75 'os.direntry':239 'output':424,505 'outsid':164,547 'parallel':652 'particular':272 'pass':330,334,383 'pass-by-valu':382 'path':85 'pattern':44,49,92,526,628 'perform':3,11,15,43,48,77 'performance-crit':14 'performance-specif':76 'pointer':335,364 'possibl':205 'pprof':501 'preemptiv':252 'prefer':97,197 'prematur':88 'primit':103 'principl':663 'process':367 'profil':464,480,499 'provid':226,264 'quick':524 'rand.int':114 'reach':305 'read':132,186,442,489 'readabl':678 'realloc':327 'refer':348,525 'references/benchmarks.md':490,491 'references/string-optimization.md':133,134,187,188,443,444 'relat':606 'repeat':151,191,539,599 'requir':261 'resiz':218 'result':66,496 'reus':661 'right':410 'run':53,70,510 's1':588 's2':589 'save':65,341 'script':51 'scripts/bench-compare.sh':52,72,512 'section':17 'see':610,629,646,664 'semant':626 'shouldn':360 'simpl':420,585 'size':280,377,560,577 'skill':607 'skill-go-performance' 'slice':244,262,269,283,434,563,619,644 'slow':10,24 'small':374,389,398,574 'source-cxuu' 'specif':78 'specifi':198,201 'speed':120 'str':542 'strategi':411,450 'strconv':98,106,138 'strconv.itoa':113,127,535 'string':27,105,153,160,238,369,371,372,387,406,419,448,532,579,581,586,595,597 'string-to-byt':152 'strings.builder':428,452,600 'strings.join':431 'struct':390,393,399 'structur':609,614 'style':662,667 'subsequ':213,296 'support':64 'sync.pool':658 'tabl':149 'test':484 'text':441 'throughout':356 'time':57,307 'to/from':104 'tool':481 'topic-agent-skills' 'topic-ai-agent' 'topic-ai-assistant' 'topic-claude' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-golang' 'topic-llm' 'type':142,386,427 'understand':624 'unlik':243,281 'use':4,19,451,471,592,635,657 'user':22,38 'v':555,559 'valid':506 'valu':331,385 'version':320 'via':62 'vs':603 'w.write':178 'whether':672 'work':653 'world':171 'worth':676 'write':13,493 'x':352,355 'zero':300,326","prices":[{"id":"8eaa1fd7-34f4-4c92-880e-2113ee1b0879","listingId":"b016de6e-177a-4d60-a19a-5ba4c8d1ea9c","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cxuu","category":"golang-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:13:20.404Z"}],"sources":[{"listingId":"b016de6e-177a-4d60-a19a-5ba4c8d1ea9c","source":"github","sourceId":"cxuu/golang-skills/go-performance","sourceUrl":"https://github.com/cxuu/golang-skills/tree/main/skills/go-performance","isPrimary":false,"firstSeenAt":"2026-04-18T22:13:20.404Z","lastSeenAt":"2026-05-02T12:55:18.992Z"}],"details":{"listingId":"b016de6e-177a-4d60-a19a-5ba4c8d1ea9c","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cxuu","slug":"go-performance","github":{"repo":"cxuu/golang-skills","stars":82,"topics":["agent-skills","ai-agent","ai-assistant","claude","claude-code","codex","cursor","go","golang","llm"],"license":"apache-2.0","html_url":"https://github.com/cxuu/golang-skills","pushed_at":"2026-03-15T19:32:10Z","description":"AI Agent Skills for idiomatic, production-ready Go code, distilled from Google, Uber, Community","skill_md_sha":"c61960d5c294e747ab89582509548e76b24a7014","skill_md_path":"skills/go-performance/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cxuu/golang-skills/tree/main/skills/go-performance"},"layout":"multi","source":"github","category":"golang-skills","frontmatter":{"name":"go-performance","license":"Apache-2.0","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)."},"skills_sh_url":"https://skills.sh/cxuu/golang-skills/go-performance"},"updatedAt":"2026-05-02T12:55:18.992Z"}}