<

Go Optimizations

Published: 2025-02-05

String operations

// Bad: Inefficient string concatenation
func concatenateStrings(parts []string) string {
    s := ""
    for _, p := range parts {
        s += p
    }
    return s
}

// Good: Efficient string.Builder usage
func buildString(parts []string) string {
    var sb strings.Builder
    sb.Grow(sumOfLengths(parts)) // Optional: pre-allocate capacity
    for _, p := range parts {
        sb.WriteString(p)
    }
    return sb.String()
}

// Helper for Grow (example)
func sumOfLengths(parts []string) int {
    total := 0
    for _, p := range parts {
        total += len(p)
    }
    return total
}

JSON handling

// Bad: Using map for JSON unmarshalling/marshalling
// map[string]interface{} incurs runtime reflection and interface allocations.
func unmarshalToMap(data []byte) (map[string]interface{}, error) {
    var m map[string]interface{}
    err := json.Unmarshal(data, &m)
    return m, err
}

// Good: Using struct for JSON unmarshalling/marshalling
// Structs are type-safe and more performant as fields are known at compile time.
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Email string `json:"email"`
}

func unmarshalToStruct(data []byte) (*User, error) {
    var user User
    err := json.Unmarshal(data, &user)
    return &user, err
}

Objects pool

// Buffer pool - reuse instead of recreate
var bufferPool = sync.Pool{
    New: func() interface{} {
        return bytes.NewBuffer(make([]byte, 0, 1024))
    },
}
func encodeResponse(data interface{}) ([]byte, error) {
    buf := bufferPool.Get().(*bytes.Buffer)
    defer func() {
        buf.Reset()
        bufferPool.Put(buf)
    }()
    encoder := json.NewEncoder(buf)
    if err := encoder.Encode(data); err != nil {
        return nil, err
    }
    result := make([]byte, buf.Len())
    copy(result, buf.Bytes())
    return result, nil
}

Compiler flags and profiling

# Analyze escape analysis with gcflags
go build -gcflags="-m -m" your_package/your_main.go

# Build with Profile-Guided Optimization (PGO)
go build -pgo=cpu.pprof -o myapp ./cmd/myapp

# Start pprof analysis server
go tool pprof -http=":8080" cpu.pprof

# Generate a CPU profile for a running application (replace PID)
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# Generate a heap profile for a running application
go tool pprof http://localhost:6060/debug/pprof/heap

Overall