A veces, es necesario analizar el rendimiento de nuestra aplicación para que funcione más rápido o simplemente para que no se caiga después de un tiempo debido a un memory leak
.
Afortunadamente, Go ya incluye herramientas para depurar estos problemas de manera nativa, una de esas es el paquete pprof
, el cual genera un formato estándar que puede ser interpretado por diferentes aplicaciones y hasta puede ser graficado.
Para analizar este código usaremos el paquete github.com/pkg/profile
para simplificar la integración con pprof
:
go get -u -v github.com/pkg/profile
Y para visualizar el resultado usaremos diago
:
go get -u -v github.com/remeh/diago
Después de instalar las herramientas que necesitamos, supongamos el siguiente código:
func buildArray(size int) []int {
arr := make([]int, 0)
for i := 0; i < size; i++ {
arr = append(arr, size)
}
return arr
}
Ahora escribamos un benchmark para hacer analizar el uso de CPU:
func Benchmark_buildArray(b *testing.B) {
defer profile.Start(profile.CPUProfile).Stop()
for i := 0; i < b.N; i++ {
_ = buildArray(10_000_000)
}
}
y ahora corramos el benchmark:
go test -bench buildArray .
Después de terminar veremos en la terminal algo como:
2020/03/22 10:25:33 profile: cpu profiling disabled, /ruta/a/un/archivo.pprof
que podremos visualizar con diago
:
diago -file /ruta/a/un/archivo.pprof
Lo que mostraría algo así:
Para evitar que buildArray
crezca el slice todo el tiempo se puede reservar memoria desde el principio:
...
arr := make([]int, 0, size)
...
Si nos interesa analizar el uso de memoria podemos cambiar el profiler así:
func Benchmark_buildArray(b *testing.B) {
defer profile.Start(profile.MemProfile).Stop()
for i := 0; i < b.N; i++ {
_ = buildArray(10_000_000)
}
}
Con el siguiente resultado:
En este caso es claro que la función está creando un array gigante pero en muchos casos no es tan fácil de ver y ahí es dónde este método sirve de gran ayuda.