MCP HubMCP Hub
SKILL·C848DC

go-performance-review

eduardo-sl
更新日 27 days ago
7 閲覧
70
9
70
GitHubで表示
開発general

について

このスキルは、Goコードにおけるパフォーマンスのボトルネックと最適化の機会を特定し、特にメモリ割り当て、文字列処理、データ構造の使用に焦点を当てます。スライスの事前割り当て、sync.Poolの使用法、pprofプロファイリングのガイダンスといった具体的な手法を提供します。Goアプリケーションのホットパスをベンチマーク、プロファイリング、または最適化する必要がある場合にご利用ください。

クイックインストール

Claude Code

推奨
メイン
npx skills add eduardo-sl/go-agent-skills -a claude-code
プラグインコマンド代替
/plugin add https://github.com/eduardo-sl/go-agent-skills
Git クローン代替
git clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-performance-review

このコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします

ドキュメント

Go Performance Review

Profile first, optimize second. Never optimize without a benchmark proving the problem.

1. Allocation Reduction

Prefer strconv over fmt for primitive conversions:

// ✅ Good — zero allocations for simple conversions
s := strconv.Itoa(42)
s := strconv.FormatFloat(3.14, 'f', 2, 64)

// ❌ Bad — fmt.Sprintf allocates
s := fmt.Sprintf("%d", 42)

Avoid unnecessary string-to-byte conversions:

// ✅ Good — use strings.Builder for concatenation
var b strings.Builder
for _, s := range parts {
    b.WriteString(s)
}
result := b.String()

// ❌ Bad — repeated concatenation allocates on every +
result := ""
for _, s := range parts {
    result += s
}

Preallocate slices and maps when size is known:

// ✅ Good — single allocation
users := make([]User, 0, len(ids))
for _, id := range ids {
    users = append(users, getUser(id))
}

// ✅ Good — map with capacity hint
lookup := make(map[string]User, len(users))

// ❌ Bad — repeated growing
var users []User // starts at 0, grows via doubling

Use sync.Pool for frequently allocated, short-lived objects:

var bufPool = sync.Pool{
    New: func() interface{} {
        return new(bytes.Buffer)
    },
}

func process(data []byte) string {
    buf := bufPool.Get().(*bytes.Buffer)
    defer func() {
        buf.Reset()
        bufPool.Put(buf)
    }()

    buf.Write(data)
    return buf.String()
}

2. Hot Path Optimizations

Avoid interface conversions in tight loops:

// ✅ Good — concrete type in loop
func sum(vals []int64) int64 {
    var total int64
    for _, v := range vals {
        total += v
    }
    return total
}

// ❌ Bad — interface{} causes boxing/unboxing
func sum(vals []interface{}) int64 { ... }

Avoid reflect in performance-critical paths:

If you need reflection-like behavior at scale, use code generation (go generate, stringer, protocol buffers).

Reduce pointer chasing:

// ✅ Good — contiguous memory, cache-friendly
type Points struct {
    X []float64
    Y []float64
}

// ❌ Slower — pointer chasing per element
type Points []*Point

3. Map Performance

// ✅ Use capacity hints
m := make(map[string]int, expectedSize)

// ✅ For read-heavy concurrent access, use sync.Map
// But ONLY when keys are stable — sync.Map has higher overhead
// for writes than a mutex-protected map.

// ✅ For fixed key sets, consider using a slice with index mapping
// instead of a map.

4. Benchmarking

ALWAYS write benchmarks before and after optimization:

func BenchmarkFoo(b *testing.B) {
    // Setup outside the loop
    input := generateInput()

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        result = Foo(input) // assign to package-level var to prevent elision
    }
}

// Package-level var prevents compiler from eliminating the call
var result string

Run benchmarks with memory profiling:

go test -bench=BenchmarkFoo -benchmem -count=5 ./...

Compare before/after with benchstat:

go test -bench=. -count=10 > old.txt
# make changes
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txt

5. Profiling

CPU profiling:

go test -cpuprofile=cpu.prof -bench=BenchmarkFoo .
go tool pprof cpu.prof

Memory profiling:

go test -memprofile=mem.prof -bench=BenchmarkFoo .
go tool pprof -alloc_space mem.prof

HTTP server profiling (import net/http/pprof):

import _ "net/http/pprof"

// Access at http://localhost:6060/debug/pprof/
go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
}()

6. High-Throughput Logging

log/slog is the right default for most services. But when benchmarks show logging is a bottleneck (high-frequency hot paths, >100k log lines/sec), consider zero-allocation loggers.

When slog is not enough:

// slog allocates per log call — fine for most services
slog.Info("request handled",
    slog.String("method", method),
    slog.Int("status", status),
)

// In hot paths where benchmarks prove logging is a bottleneck,
// use zap's zero-allocation core:
logger, _ := zap.NewProduction()
logger.Info("request handled",
    zap.String("method", method),
    zap.Int("status", status),
)
// zap avoids allocations by using a field pool and typed fields

Decision tree:

ScenarioLogger
General service logginglog/slog (stdlib, zero dependencies)
High-frequency hot path (>100k lines/sec)go.uber.org/zap (zero-alloc)
Extreme throughput with JSONgithub.com/rs/zerolog (zero-alloc JSON)

Best of both worlds — use zap as slog backend:

// Use slog API everywhere, backed by zap's performance
zapLogger, _ := zap.NewProduction()
slogHandler := zapslog.NewHandler(zapLogger.Core(), nil)
logger := slog.New(slogHandler)

// Code uses standard slog API — can swap backend without changing callers
logger.Info("request handled",
    slog.String("method", method),
    slog.Int("status", status),
)

Logging anti-patterns in hot paths:

// ❌ Bad — logging inside tight loop
for _, item := range millions {
    slog.Info("processing item", slog.String("id", item.ID))
    process(item)
}

// ✅ Good — sample or batch log
for i, item := range millions {
    process(item)
    if i%10000 == 0 {
        slog.Info("progress", slog.Int("processed", i), slog.Int("total", len(millions)))
    }
}

// ✅ Good — log summary after loop
slog.Info("batch complete", slog.Int("count", len(millions)))

NEVER switch loggers without a benchmark proving the need. slog is fast enough for the vast majority of Go services.

7. Common Anti-Patterns

Anti-PatternFix
fmt.Sprintf for simple int→stringstrconv.Itoa
String concatenation in loopstrings.Builder
Slice without preallocationmake([]T, 0, n)
Map without capacity hintmake(map[K]V, n)
regexp.Compile inside functionCompile once at package level
json.Marshal in hot pathUse code-gen (easyjson, sonic)
Logging in tight loopBatch or sample
defer in very tight inner loopManual cleanup (rare, benchmark first)

Important Caveat

Most Go code is not performance-critical. Readability and correctness ALWAYS take priority over micro-optimizations. Only apply these patterns when:

  1. A benchmark proves this code path is a bottleneck
  2. The optimization is significant (>10% improvement)
  3. The resulting code remains readable and maintainable

Premature optimization is still the root of all evil, even in Go.

GitHub リポジトリ

eduardo-sl/go-agent-skills
パス: skills/(safety)/go-performance-review
0
FAQ

よくある質問

go-performance-review Skillとは何ですか?

go-performance-review はeduardo-sl が作成した Claude Skillです。Skillは、Claudeが必要に応じて読み込む指示とリソースをまとめ、追加の指示なしで go-performance-review に関連するタスクを実行できるようにします。

go-performance-review をインストールするには?

このページのインストールコマンドを使用してください。go-performance-review をプラグインとして Claude Code に追加するか、リポジトリを skills ディレクトリにクローンし、Claudeを再起動してSkillを読み込みます。

go-performance-review はどのカテゴリに属しますか?

go-performance-review は 開発 カテゴリに属します。

go-performance-review は無料で利用できますか?

はい。go-performance-review は AIMCP に掲載されており、無料でインストールできます。

関連スキル

qmd
開発

qmdは、BM25、ベクトル埋め込み、およびリランキングを組み合わせたハイブリッド検索を用いて、ローカルファイルのインデックス作成と検索を可能にするローカル検索・インデックス作成CLIツールです。コマンドラインでの使用と、Claudeとの統合のためのMCP(Model Context Protocol)モードの両方をサポートしています。このツールは埋め込みにOllamaを使用し、インデックスをローカルに保存するため、ターミナルから直接ドキュメントやコードベースを検索するのに最適です。

スキルを見る
subagent-driven-development
開発

このスキルは、各独立したタスクに対して新規のサブエージェントを起動し、タスク間でコードレビューを実施しながら実装計画を実行します。レビュープロセスを通じて品質基準を維持しつつ、迅速な反復を可能にします。同一セッション内で主に独立したタスクに取り組む際に本スキルをご利用いただくことで、組み込まれた品質チェックを伴う継続的な進捗を確保できます。

スキルを見る
mcporter
開発

mcporterスキルは、開発者がClaudeから直接Model Context Protocol(MCP)サーバーを管理および呼び出せるようにします。このスキルは、利用可能なサーバーの一覧表示、引数を指定したツールの呼び出し、認証およびデーモンのライフサイクル管理を行うコマンドを提供します。開発ワークフローにおいてMCPサーバーの機能を統合およびテストする際に、このスキルをご利用ください。

スキルを見る
adk-deployment-specialist
開発

このスキルは、A2Aプロトコルを使用してVertex AI ADKエージェントをデプロイおよびオーケストレーションし、AgentCardの発見、タスク送信、およびコード実行サンドボックスやメモリバンクなどのサポートツールを管理します。Python、Java、またはGoで、順次、並列、またはループのオーケストレーションパターンを用いたマルチエージェントシステムの構築を可能にします。Google Cloud上でADKエージェントのデプロイやエージェントワークフローのオーケストレーションを求められた際にご利用ください。

スキルを見る