این جزوه به بررسی جامع ابزارها و تکنیکهای بهینهسازی در Go میپردازد. Go با ابزارهای داخلی و خارجی قدرتمند، امکان پروفایلینگ، مدیریت حافظه، ساخت برنامههای کارآمد، و یکپارچهسازی با فرآیندهای توسعه را فراهم میکند. تمام موضوعات درخواستی با جزئیات کامل و مثالهای عملی شرح داده شدهاند.
پروفایلینگ و دیباگ برای شناسایی گلوگاههای عملکرد و اشکالات برنامه ضروری هستند. Go ابزارهای داخلی مثل pprof
، trace
، و go tool
را ارائه میدهد.
pprof
ابزاری برای پروفایلینگ برنامههای Go است که اطلاعاتی درباره مصرف CPU، حافظه، و goroutineها ارائه میدهد.
پکیج net/http/pprof
را به برنامه اضافه کنید:
package main
import (
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// کد برنامه
select {}
}
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
این دستور 30 ثانیه داده جمعآوری کرده و وارد محیط تعاملی pprof
میشود.
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/goroutine
در محیط pprof
:
(pprof) top
(pprof) web
(pprof) list main.myFunction
فرض کنید برنامهای دارید که CPU زیادی مصرف میکند:
package main
import (
"net/http"
_ "net/http/pprof"
)
func heavyComputation() {
for i := 0; i < 1000000; i++ {
_ = i * i
}
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
heavyComputation()
w.Write([]byte("Done"))
})
http.ListenAndServe(":8080", nil)
}
go run main.go
go tool pprof http://localhost:6060/debug/pprof/profile
top
نشان میدهد heavyComputation
منابع زیادی مصرف میکند.trace
برای تحلیل اجرای برنامه در سطح goroutineها و زمانبندی استفاده میشود.
package main
import (
"log"
"os"
"runtime/trace"
)
func main() {
f, err := os.Create("trace.out")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := trace.Start(f); err != nil {
log.Fatal(err)
}
defer trace.Stop()
// کد برنامه
for i := 0; i < 10; i++ {
go func() {
time.Sleep(time.Millisecond * 100)
}()
}
time.Sleep(time.Second)
}
go tool trace trace.out
این دستور یک رابط وب باز میکند که شامل:
go tool
ابزارهای مختلفی برای دیباگ ارائه میدهد:
go tool objdump -s main.main mybinary
go tool nm mybinary
pprof
با احتیاط استفاده کنید (با احراز هویت).go run -race main.go
go get -u github.com/go-delve/delve/cmd/dlv
dlv debug main.go
-race
.مدیریت حافظه در Go توسط Garbage Collector (GC) انجام میشود، اما تکنیکهایی مثل sync.Pool
و بهینهسازی GC میتوانند کارایی را بهبود دهند.
sync.Pool
برای مدیریت اشیاء موقت و کاهش فشار روی GC استفاده میشود. مناسب برای اشیائی که مکرراً ایجاد و دور ریخته میشوند.
package main
import (
"bytes"
"fmt"
"sync"
)
var pool = sync.Pool{
New: func() interface{} {
return &bytes.Buffer{}
},
}
func main() {
buf := pool.Get().(*bytes.Buffer)
buf.WriteString("Hello")
fmt.Println(buf.String())
buf.Reset()
pool.Put(buf)
}
Put
بازنشانی کنید (مثل buf.Reset()
).sync.Pool
thread-safe است.GOGC
رفتار GC را کنترل میکند (پیشفرض 100):
GOGC=200
: GC کمتر اجرا میشود (مصرف حافظه بیشتر).GOGC=50
: GC مکرر اجرا میشود (مصرف CPU بیشتر).export GOGC=200
go run main.go
s := make([]int, 0, 1000)
go build -gcflags="-m"
این دستور نشان میدهد کدام متغیرها به heap منتقل میشوند.
package main
import (
"fmt"
"runtime"
)
func main() {
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
fmt.Printf("Heap Alloc: %v bytes\n", ms.HeapAlloc)
// تخصیص زیاد
for i := 0; i < 1000000; i++ {
_ = make([]byte, 100)
}
runtime.ReadMemStats(&ms)
fmt.Printf("Heap Alloc after: %v bytes\n", ms.HeapAlloc)
runtime.GC() // اجرای دستی GC (فقط برای تست)
}
go tool pprof http://localhost:6060/debug/pprof/heap
runtime.SetFinalizer(obj, func(o *Type) {
// آزادسازی
})
sync.Pool
.GOGC
بدون تست.Go فرآیند ساخت سادهای دارد، اما تکنیکهایی برای بهینهسازی اندازه باینری و cross-compilation وجود دارد.
go build -o myapp main.go
myapp
.go build -ldflags="-s -w" -o myapp
-s
: حذف جدول سمبلها.-w
: حذف اطلاعات DWARF.upx --brute myapp
برای ساخت باینری برای سیستمعاملها و معماریهای دیگر:
GOOS=linux GOARCH=amd64 go build -o myapp-linux main.go
GOOS=windows GOARCH=amd64 go build -o myapp.exe main.go
ساخت برای لینوکس از مک:
GOOS=linux GOARCH=amd64 go build -o myapp-linux main.go
go mod tidy
CGO_ENABLED=0 go build -o myapp
CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-extldflags '-static'" -o myapp
// +build prod
package main
go build -tags prod
go build -ldflags="-X main.version=1.0.0" -o myapp
var version string
fmt.Println("Version:", version)
GOOS
/GOARCH
برای cross-compilation.لینت و فرمت کد برای حفظ کیفیت و خوانایی کد ضروری هستند.
gofmt
ابزار استاندارد برای فرمت کد است.
gofmt -w main.go
gofmt
را اجرا میکنند.golint
پیشنهادهایی برای بهبود سبک کد ارائه میدهد.
go install golang.org/x/lint/golint@latest
golint ./...
main.go:10:1: exported function Foo should have comment or be unexported
staticcheck
ابزار پیشرفتهتری برای تحلیل کد است.
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
package main
func main() {
x := 1
// x استفاده نمیشود
}
staticcheck main.go
main.go:3:6: x is unused (U1000)
pre-commit
برای اجرای gofmt
و staticcheck
استفاده کنید:
```yaml
repos:
revive
: جایگزین سریعتر برای golint
.golangci-lint
: ترکیبی از چندین ابزار لینت:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run
gofmt
قبل از commit.CI/CD (Continuous Integration/Continuous Deployment) فرآیند خودکارسازی تست، بیلد، و استقرار است.
GitHub Actions برای اجرای خودکار وظایف CI/CD استفاده میشود.
name: Go CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
- name: Install dependencies
run: go mod download
- name: Run tests
run: go test -v ./...
- name: Run linters
uses: golangci/golangci-lint-action@v6
with:
version: latest
- name: Build
run: go build -o myapp
golangci-lint
.داکر برای بستهبندی و استقرار برنامهها استفاده میشود.
FROM golang:1.20 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]
docker build -t myapp .
docker run -p 8080:8080 myapp
kubectl apply -f deployment.yaml
go test -tags=integration ./...
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
sync.Pool
برای اشیاء پرتکرار و ظرفیت اولیه برای اسلایسها استفاده کنید.-ldflags="-s -w"
و CGO_ENABLED=0
برای باینریهای تولید استفاده کنید.این جزوه تمام جنبههای ابزارها و بهینهسازی در Go را با جزئیات کامل پوشش داد. از پروفایلینگ با pprof
و trace
تا مدیریت حافظه با sync.Pool
، ساخت باینریهای بهینه، لینت کد، و تنظیم CI/CD، هر بخش با مثالهای عملی و نکات پیشرفته ارائه شد. برای یادگیری عمیقتر:
https://golang.org/doc/