Ускорьте свои API
Создание новых объектов может быть относительно дорогостоящей операцией, особенно если она включает в себя выделение памяти в куче, поэтому повторное использование объектов может помочь уменьшить накладные расходы и повысить производительность. Сохраняя пул объектов preAllocated и повторно используя их по мере необходимости, мы можем избежать накладных расходов на выделение и освобождение памяти (сборщик мусора освобождает неиспользуемые переменные в памяти).
Это может быть особенно полезно для API, которым необходимо обрабатывать большое количество запросов, где создание и уничтожение объектов по каждому запросу может быть существенным узким местом. Повторно используя объекты, мы можем уменьшить количество требуемого процессорного времени и памяти, что может привести к повышению производительности и способности обрабатывать больше запросов.
Для этого мы можем использовать sync.Poolпакет в Go для реализации пула объектов. Это sync.Poolвстроенный пакет Go, предоставляющий потокобезопасный механизм для хранения и извлечения объектов из пула.
Можно напрямую перейти в код..!!
Обработчики: -
package handlers
import (
"encoding/json"
"net/http"
"sync"
)
type Request struct {
Name string `json:"name"`
Id string `json:"id"`
Country string `json:"country"`
Age int `json:"age"`
}
type ObjectPool struct {
ReqPool *sync.Pool
}
var objPool ObjectPool
func init() {
// init object pool
objPool.ReqPool = &sync.Pool{
New: func() interface{} {
return new(Request)
},
}
}
func HandlerWithoutSyncPool() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req :=new(Request)
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(req)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
})
}
func HandlerWithSyncPool() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req := objPool.ReqPool.Get().(*Request)
//to make sure it return object to pool
defer objPool.ReqPool.Put(req)
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
})
}
Примечание: результаты зависят от типа объекта, который мы объединяем.
package handlers
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
var tests = []struct {
req Request
}{
{
req: Request{Name: "test", Country: "testCountry", Id: "id1", Age: 10},
},
}
func BenchmarkHandlerWithSyncPool(b *testing.B) {
for _, test := range tests {
data, _ := json.Marshal(test)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, _ = http.Post("http://127.0.0.1:8888/withpool", "application/json", bytes.NewBuffer(data))
}
})
}
}
func BenchmarkHandlerWithoutSyncPool(b *testing.B) {
for _, test := range tests {
data, _ := json.Marshal(test)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, _ = http.Post("http://127.0.0.1:8888/withoutpool", "application/json", bytes.NewBuffer(data))
}
})
}
}
go test -bench=BenchmarkHandlerWithoutSyncPool -benchtime=5s -cpu=1
goos: darwin
goarch: amd64
pkg: testsyncpool/handlers
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkHandlerWithoutSyncPool 23067 1004690 ns/op
go test -bench=BenchmarkHandlerWithSyncPool -benchtime=5s -cpu=1
goos: darwin
goarch: amd64
pkg: testsyncpool/handlers
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkHandlerWithSyncPool 77290 76521 ns/op
package main
import (
"log"
"net/http"
"net/http/pprof"
"testsyncpool/handlers"
)
func main() {
r := http.NewServeMux()
//r.Handle("/withoutpool", handlers.HandlerWithoutSyncPool())
r.Handle("/withpool", handlers.HandlerWithSyncPool())
// Register pprof handlers
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)
err := http.ListenAndServe(":8888", r)
if err != nil {
log.Fatal(err)
}
}
Пожалуйста, не стесняйтесь добавлять любые комментарии/предложения/ошибки и т. д.…

![В любом случае, что такое связанный список? [Часть 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































