Golang Performance Benchmark Test (Benchmark) Detailed Explanation

Golang performance benchmarking can help developers compare the impact of different implementations on performance in order to optimize the program. This article will explain how to use Golang's performance benchmarking function.

Golang Performance Benchmarks

Performance benchmarking in Golang is implemented using standard library tests, and writing performance test code is easy:

Create a performance test file: Create a new file in the source code directory of the Go project (in the same package as the tested code file), with the suffix _test.go. For example, to test the method in dial.go in the net package, create a file named dial_test.go in the net package, which is the same as the unit test file.

Import the testing package: import the testing package in the test file to use related functions and tools.

Write a test function: In the test file, write a function prefixed with Benchmark, followed by one or more characters or character combinations to identify the name of the test case (generally use the name of the function under test), the parameter must be b * testing. B.

Write test code: bN is provided by the benchmark test framework, which represents the number of loops, because the test code needs to be called repeatedly to evaluate performance. The value of bN will increase in the order of 1, 2, 5, 10, 20, 50, ... until the running time is greater than 1 second. The program will stop running because it judges that the running time is stable, so it must not be in the loop Use a varying value as an argument to a function.

Take the json format verification tool https://github.com/luduoxin/json-validator-go as an example, the key function Valid in the scanner.go file in the validator package is used to verify whether a given string is in json format, corresponding to The performance test file is scanner_test.go, the test function inside is BenchmarkValid, the code is as follows:

package validator
  import "testing"
  func BenchmarkValid(b *testing.B) {
  str := `{"foo":"bar"}`
  b.ResetTimer()
  for i := 0; i < b.N; i++ {
  Valid([]byte(str))
  }

 

Run performance test cases

The performance test command is go test [parameter], such as go test -bench=. The specific command parameters and their meanings are as follows:

-bench regexp performance test, run the specified test letter.

-bench . Run all benchmark function tests, and specify the name to only execute specific test methods instead of all.

-benchmem Displays memory allocation statistics for test functions during performance testing.

-count n How many times to run the test and performance, the default is once.

-run regexp Only run specific test functions.

-timeout t panic if the test time exceeds t, the default is 10 minutes.

-v Displays detailed information about the test.

Start the command line, switch to the validator folder of the json-validator-go project, and run all performance test cases:

$ go test -bench=.
  goos: darwin
  goarch: amd64
  pkg: github.com/luduoxin/json-validator-go/validator
  cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  BenchmarkValid-8        13562608                86.55 ns/op
  PASS
  ok      github.com/luduoxin/json-validator-go/validator 1.420s

 

The contents of the third-to-last line of information in the output report above have the following meanings:

BenchmarkValid is the name of the performance test function, -8 means that the value of GOMAXPROCS is 8, 13562608 means that it has been executed a total of 13562608 times, which is the value of bN, and 86.55 ns/op means that each operation takes an average of 86.55 nanoseconds.

You can also run multiple use cases in one test method, and use more types of data to see the corresponding performance. The code is as follows:

 package validator
  import "testing"
  func BenchmarkValid(b *testing.B) {
  var validTests = []struct {
  data string
  ok   bool
  }{
  {`foo`, false},
  {`}{`, false},
  {`{]`, false},
  {`{}`, true},
  {`[{}]`, true},
  {`{"foo":"bar"}`, true},
  {`{"foo":"bar","bar":{"baz":["qux"]}}`, true},
  }
  for _, v := range validTests {
  b.Run("", func(b *testing.B) {
  for i := 0; i < b.N; i++ {
  Valid([]byte(v.data))
  }
  })
  }
  }

Run to see the effect:

$ go test -bench=. 
  goos: darwin
  goarch: amd64
  pkg: github.com/luduoxin/json-validator-go/validator
  cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  BenchmarkValid/#00-8             4746290               249.8 ns/op
  BenchmarkValid/#01-8             4841005               245.5 ns/op
  BenchmarkValid/#02-8             4610671               257.0 ns/op
  BenchmarkValid/#03-8            26957421                42.63 ns/op
  BenchmarkValid/#04-8            29747263                41.88 ns/op
  BenchmarkValid/#05-8            20895832                56.31 ns/op
  BenchmarkValid/#06-8            14058906                83.17 ns/op
  BenchmarkValid/#07-8             5518412               212.9 ns/op
  PASS
  ok      github.com/luduoxin/json-validator-go/validator 10.891s

Finally, I would like to thank everyone who has read my article carefully. Reciprocity is always necessary. Although it is not a very valuable thing, you can take it away if you need it:

These materials should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse has also accompanied tens of thousands of test engineers through the most difficult journey, and I hope it can help you! Partners can click the small card below to receive  

Guess you like

Origin blog.csdn.net/kk_lzvvkpj/article/details/132085121