Profiling

back

Profiling is a way to analyse the performance and behavior of a Go program, such as its CPU usage, memory allocation, blocking operations, and more.

sample one 1

A function that creates a string, gets a string length, and creates a string from the length.

sample code
// main.go
package main

import (
  "fmt"
  "strconv"
)

func createString(size int) string {
  var str string
  for i := 0; i < size; i++ {
    str += strconv.Itoa(i) // convert integer to string and concatenate
  }
  return str
}

func main() {
  fmt.Println("vim-go")
}
// main_test.go
package main

import "testing"

func BenchmarkCreateString(b *testing.B) {
  for i := 0; i < b.N; i++ {
    createString(1000)
  }
}
go mod init ilima.xyz/profiling-in-golang/20231228
go mod tidy

# `go test -bench=.` Runs all available benchmarks in the current package or directory.
# `-bench=CreateString` This is an optional parameter. If specified, only benchmark functions whose names contain the pattern “CreateString” will be run.
# `-benchmem` Enables memory profiling and generates a memory profile file (mem.prof) after the benchmarks are run.
# `-cpuprofile cpu.prof` Enables CPU profiling and generates a CPU profile file (cpu.prof) after the benchmarks are run.
# `-benchtime=5s` Sets the benchmark duration to 5 seconds.
go test -bench=. -benchmem -cpuprofile cpu.prof -memprofile mem.prof -benchtime=5s

# run this command below to see how much memory our test has consumed
# “mem.prof” is the name of the file that has been generated by the command we already used above.
go tool pprof mem.prof
help
top
list profiling-in-golang/20231228.createString
exit

# check the cpu.prof
go tool pprof cpu.prof
tree
list profiling-in-golang/20231228.createString
exit

# let’s check them graphically to see how it’s going by adding the -http flag to the pprof command.
go tool pprof -http=:8080 cpu.prof
# run the command below to show a specific memory profile generated using the pprof tool
go tool pprof -http=:8080 mem.prof
cpu.prof mem.prof
image image
fixing it...
func createStringOne(size int) string {
  var str string
  for i := 0; i < size; i++ {
    str += strconv.Itoa(i) // Convert integer to string and concatenate
  }
  return str
}

func createStringTwo(size int) string {
  var buffer bytes.Buffer
  for i := 0; i < size; i++ {
    buffer.WriteString(strconv.Itoa(i))
  }

  return buffer.String()
}
func BenchmarkCreateStringOne(b *testing.B) {
  for i := 0; i < b.N; i++ {
    createStringOne(1000)
  }
}

func BenchmarkCreateTestTwo(b *testing.B) {
  for i := 0; i < b.N; i++ {
    createStringTwo(1000)
  }
}