Acelera tus API
La creación de nuevos objetos puede ser una operación relativamente costosa, especialmente si implica asignar memoria en el montón, por lo que la reutilización de objetos puede ayudar a reducir la sobrecarga y mejorar el rendimiento. Al mantener un conjunto de objetos preasignados y reutilizarlos según sea necesario, podemos evitar la sobrecarga de asignar y desasignar memoria (el recolector de basura desasigna las variables no utilizadas en la memoria).
Esto puede ser especialmente útil para las API que necesitan manejar una gran cantidad de solicitudes, donde la creación y destrucción de objetos en cada solicitud puede ser un cuello de botella importante. Al reutilizar objetos, podemos reducir la cantidad de tiempo de CPU y memoria requerida, lo que puede generar un mejor rendimiento y la capacidad de manejar más solicitudes.
Para lograr esto, podemos usar el sync.Poolpaquete en Go para implementar la agrupación de objetos. Es sync.Poolun paquete de Go incorporado que proporciona un mecanismo seguro para subprocesos para almacenar y recuperar objetos de un grupo.
Puede saltar directamente al código ..!!
Manejadores:-
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)
})
}
Nota: los resultados varían según el tipo de objeto que estamos agrupando
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)
}
}
Por favor, siéntase libre de agregar cualquier comentario/sugerencia/errores, etc...

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































