Skip to content

Go static analyzer that detects allocation-heavy patterns in loops (string concat, json, regexp, etc.)

License

Notifications You must be signed in to change notification settings

SHCDevelops/galo

Repository files navigation

galo

CI Go Version Release License

Go Auto Latency/Alloc Optimizer — static analyzer that detects performance anti-patterns in Go code.

galo finds common mistakes that cause unnecessary allocations and CPU overhead: string concatenation in loops, missing preallocation, regexp compilation inside functions, and more.

Installation | Usage | Rules | Русский

Installation

One-liner (Linux/macOS)

curl -sSfL https://raw.githubusercontent.com/SHCDevelops/galo/main/install.sh | sh

Go install

go install github.com/SHCDevelops/galo/cmd/galo@latest

Download binary

Download from Releases and add to PATH.

Build from source

git clone https://github.com/SHCDevelops/galo
cd galo
make install

Usage

# Scan current module
galo scan ./...

# Scan specific packages
galo scan ./internal/... ./pkg/...

# Show only high-impact issues
galo scan --min-level L3 ./...

# Output to custom path
galo scan --out report.json ./...

Web UI

# Start local UI to explore findings
galo ui --report .galo/report.json

# Open http://127.0.0.1:7070

Rules

ID Description Tags
STR_CONCAT_LOOP String concatenation in loop alloc, hotloop
FMT_IN_LOOP fmt.Sprintf/Fprintf in loop cpu, alloc
BUILDER_NO_GROW Builder/Buffer without Grow alloc
APPEND_NO_PREALLOC Append without preallocation alloc, hotloop
CONV_IN_LOOP []byte/string conversion in loop alloc
REGEXP_COMPILE regexp.Compile inside function cpu
JSON_IN_LOOP json.Marshal/Unmarshal in loop cpu, alloc
DEFER_IN_LOOP defer inside loop cpu

Severity Levels

  • L4 — High confidence, high impact. Fix these first.
  • L3 — Medium-high confidence, noticeable impact.
  • L2 — Worth investigating in hot paths.
  • L1 — Informational, minor impact.

Example

// galo detects this pattern:
func process(items []string) string {
    var result string
    for _, item := range items {
        result += item + "," // STR_CONCAT_LOOP: O(n²) allocations
    }
    return result
}

// Suggested fix:
func process(items []string) string {
    var b strings.Builder
    b.Grow(len(items) * 10) // estimate
    for _, item := range items {
        b.WriteString(item)
        b.WriteByte(',')
    }
    return b.String()
}

Configuration

galo works without configuration. Optional .galo.yaml:

min-level: L2

exclude:
  - vendor/
  - "*_test.go"

disable:
  - DEFER_IN_LOOP

Contributing

# Run tests
make test

# Run linters
make lint

# Run galo on itself
make selfcheck

License

MIT License. See LICENSE for details.

About

Go static analyzer that detects allocation-heavy patterns in loops (string concat, json, regexp, etc.)

Resources

License

Stars

Watchers

Forks

Packages

No packages published