SoFunction
Updated on 2025-03-02

Detailed explanation of the usage example of Go programming library

Scene

go If objects are frequently created and destroyed (such as json objects, log content, etc. of http service), it will put pressure on GC. For example, the followingLogFunctions, in high concurrency cases, require frequent creation and destruction of buffers.

func Log(w , key, val string) {
	b := new()
  // Print logs in a certain format, this paragraph is not the focus	(().UTC().Format(time.RFC3339))
	(' ')
	(key)
	('=')
	(val)
	('\n')
	(())
}

You can consider reusing these buffers at this time. We can maintain a buffer object pool, and when needed, take the buffer from the object pool and put it back into the object pool after use. It is recommended to use this time.

Maintain a group of object pools. When necessary, take objects from the object pool and do not need to be put back to the object pool. It has these characteristics:

  • The object pool will be automatically expanded when busy, and the capacity will be automatically reduced when idle;
  • Thread safety;
  • Objects in the object pool will be automatically deleted without notice;
  • Can't be copied.

usage

create

Specifies the New method during initialization. An object that will be created through the New method. Generally returns a pointer.

// When taking buffers from the object pool, if there is no buffer in the pool, call New to create a new one.var bufPool = {
	New: func() interface{} {
		return new()
	},
}

GET & PUT

Get the object of the object pool through Get. When used, return the object to the object pool through Put.

  b := ().(*)  // Take buffer object from object pool  // Operation object, this is not important	()
	(().UTC().Format(time.RFC3339))
  // Put it back to the object pool after operation	(b)

Optimize Log Functions

The log function can use optimization, the code is as follows:

var bufPool = {
	New: func() interface{} {
		return new()
	},
}
func LogWithPool(w , key, val string) {
  // Take the buffer from the object pool	b := ().(*)
	()
  // Print logs in a certain format, this paragraph is not the focus	(().UTC().Format(time.RFC3339))
	(' ')
	(key)
	('=')
	(val)
	('\n')
	(())
  // Put back to the object pool	(b)
}

Performance Testing

We perform performance tests on two functions

// Not usedfunc BenchmarkLog(b *) {
	writer := (0, )
	for n := 0; n < ; n++ {
		Log(writer, "path", "/search?a=flowers")
	}
}
// Use Reusefunc BenchmarkLogWithPool(b *) {
	writer := (0, )
	for n := 0; n < ; n++ {
		LogWithPool(writer, "path", "/search?a=flowers")
	}
}

result:

> go test -bench . -benchmem
goos: darwin
goarch: amd64
pkg: example/pool
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkLog-8                   1849365               635.0 ns/op           112 B/op          2 allocs/op
BenchmarkLogWithPool-8           1993304               614.4 ns/op            48 B/op          1 allocs/op
PASS
ok      example/pool    4.333s

In contrast, when using and not using, the memory usage ratio is 48:112, and the optimization effect is quite obvious.

refer to:

[1]. /sync#Pool

The above is a detailed explanation of the usage example of Go programming library. For more information about Go library, please pay attention to my other related articles!