This collection of practical performance benchmarks of Go packages and algorithms aims to help developers write fast and efficient programs.

The following benchmarks evaluate various functionality with the focus on the usability of benchmark results.

  • String Concatenation
  • Numeric Conversions
  • Regular Expressions
  • Sorting
  • Random Numbers
  • Random Strings
  • Slice Appending
  • Map Access
  • Object Pool
  • Hash Functions
  • Base64
  • Serialization
  • Compression
  • URL Parsing
  • Templates
  • HTTP Server

Environment: Go 1.10, Linux, Intel® Core™ i7-4770HQ CPU @ 2.20GHz

String Concatenation

This benchmark evaluates the performance of string concatenation using the + operator, The bytes.Buffer and the strings.Builder when building a 1000 character string. The Implementations using the bytes.Buffer and the strings.Builder are the fastest.

package main import ( "bytes" "strings" "testing" ) var strLen int = 1000 func BenchmarkConcatString(b *testing.B) { var  str string i := 0 b.ResetTimer() for n := 0; n < b.N; n++ { str += "x" i++ if i >= strLen { i = 0 str = "" } } } func BenchmarkConcatBuffer(b *testing.B) { var buffer bytes.Buffer i := 0 b.ResetTimer() for n := 0; n < b.N; n++ { buffer.WriteString("x") i++ if i >= strLen { i = 0 buffer = bytes.Buffer{} } } } func BenchmarkConcatBuilder(b *testing.B) { var builder strings.Builder i := 0 b.ResetTimer() for n := 0; n < b.N; n++ { builder.WriteString("x") i++ if i >= strLen { i = 0 builder = strings.Builder{} } } }Copy the code
$go test-bench =. -benchmem BenchmarkConcatString-4 10,000,000 159 ns/op 530 B/op 0 allocs/op BenchmarkConcatBuffer-4 200,000,000 10 ns/op 2 B/op 0 ALlocs/OP BenchmarkConcatBuilder-4 100,000,000 11 ns/ OP 2 B/ OP 0 Allocs /opCopy the code

Numeric Conversions

This benchmark evaluates the performance of parsing strings to bool, int64 and float64 types using the Go strconv package.

package main import ( "strconv" "testing" ) func BenchmarkParseBool(b *testing.B) { for n := 0; n < b.N; n++ { _, err := strconv.ParseBool("true") if err ! = nil { panic(err) } } } func BenchmarkParseInt(b *testing.B) { for n := 0; n < b.N; n++ { _, err := strconv.ParseInt("7182818284", 10, 64) if err ! = nil { panic(err) } } } func BenchmarkParseFloat(b *testing.B) { for n := 0; n < b.N; N++ {_, err := strconv.ParseFloat("3.1415926535", 64) if err! = nil { panic(err) } } }Copy the code
$go test-bench =. -benchmem BenchmarkParseBool-4 300,000,000 4 ns/op 0 B/op 0 ALlocs /op BenchmarkParseInt-4 50,000,000 25 NS /op 0 B/op 0 ALLOCs/OP BenchmarkParseFloat-4 50,000,000 40 ns/op 0 B/ OP 0 ALlocs /opCopy the code

Regular Expressions

This benchmark evaluates the performance of regular expression matching using the Go regexp package for compiled and uncompiled regular expressions. The example uses a simple email validation regexp. As expected, the compiled regexp matching is much faster.

package main import ( "regexp" "testing" ) var testRegexp string = `^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+$` func BenchmarkMatchString(b *testing.B) { for n := 0; n < b.N; n++ { _, err := regexp.MatchString(testRegexp, "[email protected]") if err ! = nil { panic(err) } } } func BenchmarkMatchStringCompiled(b *testing.B) { r, err := regexp.Compile(testRegexp) if err ! = nil { panic(err) } b.ResetTimer() for n := 0; n < b.N; n++ { r.MatchString("[email protected]") } }Copy the code
$go test-bench =. -benchmem BenchmarkMatchString-4 100,000 17,380 ns/op 42,752 B/op 70 allocs/op BenchmarkMatchStringCompiled - 4, 2000000, 843 ns/op/op 0 0 B allocs/opCopy the code

Sorting

This benchmark evaluates the performance of sorting 1,000, 10,000, 100,000 and 1,000,000 int elements using built-in sorting algorithm of the Go sort package. The time complexity is documented to be O(n*log(n)), which can be observed in the results.

package main import ( "math/rand" "sort" "testing" ) func generateSlice(n int) []int { s := make([]int, 0, n) for i := 0; i < n; i++ { s = append(s, rand.Intn(1e9)) } return s } func BenchmarkSort1000(b *testing.B) { for n := 0; n < b.N; n++ { b.StopTimer() s := generateSlice(1000) b.StartTimer() sort.Ints(s) } } func BenchmarkSort10000(b *testing.B) { for  n := 0; n < b.N; n++ { b.StopTimer() s := generateSlice(10000) b.StartTimer() sort.Ints(s) } } func BenchmarkSort100000(b *testing.B) { for n := 0; n < b.N; n++ { b.StopTimer() s := generateSlice(100000) b.StartTimer() sort.Ints(s) } } func BenchmarkSort1000000(b *testing.B) {  for n := 0; n < b.N; n++ { b.StopTimer() s := generateSlice(1000000) b.StartTimer() sort.Ints(s) } }Copy the code
$ go test -bench=. -benchmem

BenchmarkSort1000-4     10,000      121,720 ns/op  32 B/op  1 allocs/op
BenchmarkSort10000-4     1,000    1,477,141 ns/op  32 B/op  1 allocs/op
BenchmarkSort100000-4      100   19,211,037 ns/op  32 B/op  1 allocs/op
BenchmarkSort1000000-4       5  220,539,215 ns/op  32 B/op  1 allocs/op

Copy the code

Random Numbers

This benchmark compares the performance of pseudorandom number generation using the Go math/rand and crypto/rand packages. The random number generation with the math/rand package is considerably faster than cryptographically secure random number generation with the crypto/rand package.

package main import ( crand "crypto/rand" "math/big" "math/rand" "testing" ) func BenchmarkMathRand(b *testing.B) { for n := 0; n < b.N; n++ { rand.Int63() } } func BenchmarkCryptoRand(b *testing.B) { for n := 0; n < b.N; n++ { _, err := crand.Int(crand.Reader, big.NewInt(27)) if err ! = nil { panic(err) } } }Copy the code
$go test-bench =. -benchmem BenchmarkMathRand-4 50,000,000 23 ns/op 0 B/op 0 ALlocs /op BenchmarkCryptoRand-4 1,000,000 Ns/OP 161 B/op 5 ALlocs /opCopy the code

Random Strings

This benchmark compares the performance of 16-character, uniformly distributed random string generation based on the Go math/rand and crypto/rand. The random string generation with the math/rand package is faster than cryptographically secure random string generation with the crypto/rand package.

package main import ( crand "crypto/rand" "math/rand" "testing" ) // 64 letters const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/" func randomBytes(n int) []byte { bytes := make([]byte, n) _, err := rand.Read(bytes) if err ! = nil { panic(err) } return bytes } func cryptoRandomBytes(n int) []byte { bytes := make([]byte, n) _, err := crand.Read(bytes) if err ! = nil { panic(err) } return bytes } func randomString(bytes []byte) string { for i, b := range bytes { bytes[i] = letters[b%64] } return string(bytes) } func BenchmarkMathRandString(b *testing.B) { for n : = 0; n < b.N; n++ { randomString(randomBytes(16)) } } func BenchmarkCryptoRandString(b *testing.B) { for n := 0; n < b.N; n++ { randomString(cryptoRandomBytes(16)) } }Copy the code
$go test -bench=. -benchmem BenchmarkMathRandString-4 10,000,000 119 ns/op 32 B/op 2 allocs/op BenchmarkCryptoRandString - 4, 2000000, 864 ns/op 32 B/op 2 allocs/opCopy the code

Slice Appending

This benchmark evaluates the performance of appending a byte to a slice with and without slice preallocation.

package main import ( "testing" ) var numItems int = 1000000 func BenchmarkSliceAppend(b *testing.B) { s := make([]byte,  0) i := 0 b.ResetTimer() for n := 0; n < b.N; n++ { s = append(s, 1) i++ if i == numItems { b.StopTimer() i = 0 s = make([]byte, 0) b.StartTimer() } } } func BenchmarkSliceAppendPrealloc(b *testing.B) { s := make([]byte, 0, numItems) i := 0 b.ResetTimer() for n := 0; n < b.N; n++ { s = append(s, 1) i++ if i == numItems { b.StopTimer() i = 0 s = make([]byte, 0, numItems) b.StartTimer() } } }Copy the code
$go test-bench =. -benchmem BenchmarkSliceAppend- 41,000,000,000 2 ns/op 5 B/op 0 allocs/op BenchmarkSliceAppendPrealloc - 4 1 ns/op 2000000000 0 B/op 0 allocs/opCopy the code

Map Access

This benchmark evaluates the access performance of maps with int vs string keys for 1,000,000 item maps.

package main

import (
	"math/rand"
	"strconv"
	"testing"
)

var NumItems int = 1000000

func BenchmarkMapStringKeys(b *testing.B) {
	m := make(map[string]string)
	k := make([]string, 0)

	for i := 0; i < NumItems; i++ {
		key := strconv.Itoa(rand.Intn(NumItems))
		m[key] = "value" + strconv.Itoa(i)
		k = append(k, key)
	}

	i := 0
	l := len(m)

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		if _, ok := m[k[i]]; ok {
		}

		i++
		if i >= l {
			i = 0
		}
	}
}

func BenchmarkMapIntKeys(b *testing.B) {
	m := make(map[int]string)
	k := make([]int, 0)

	for i := 0; i < NumItems; i++ {
		key := rand.Intn(NumItems)
		m[key] = "value" + strconv.Itoa(i)
		k = append(k, key)
	}

	i := 0
	l := len(m)

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		if _, ok := m[k[i]]; ok {
		}

		i++
		if i >= l {
			i = 0
		}
	}
}Copy the code
$go test -bench=. -benchmem BenchmarkMapIntKeys-4 20,000,000 20,000,000 65 ns/op 0 B/op 0 ALLOCs /opCopy the code

Object Pool

This benchmark evaluates the performance of object creation vs object reuse using sync.Pool.

package main import ( "sync" "testing" ) type Book struct { Title string Author string Pages int Chapters []string } var  pool = sync.Pool{ New: func() interface{} { return &Book{} }, } func BenchmarkNoPool(b *testing.B) { var book *Book for n := 0; n < b.N; n++ { book = &Book{ Title: "The Art of Computer Programming, Vol. 1", Author: "Donald E. Knuth", Pages: 672, } } _ = book } func BenchmarkPool(b *testing.B) { for n := 0; n < b.N; n++ { book := pool.Get().(*Book) book.Title = "The Art of Computer Programming, Vol. 1" book.Author = "Donald E. Knuth" book.Pages = 672 pool.Put(book) } }Copy the code
$go test-bench =. -benchmem BenchmarkNoPool-4 30,000,000 45 ns/op 64 B/op 1 allocs/op BenchmarkPool-4 100,000,000 22 ns/op 0 B/op 0 allocs/opCopy the code

Hash Functions

This benchmark compares the performance of multiple hash functions, including MD5, SHA1, SHA256, SHA512, SHA3-256, SHA3-512, BLAKE2d-256 and BLAKE2d-256 from internal and external Go crypto subpackages on random one kilobyte data.

package main

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"golang.org/x/crypto/blake2b"
	"golang.org/x/crypto/sha3"
	"hash"
	"math/rand"
	"testing"
)

func benchmarkHash(b *testing.B, h hash.Hash) {
	data := make([]byte, 1024)
	rand.Read(data)

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		h.Write(data)
		h.Sum(nil)
	}
}

func BenchmarkMD5(b *testing.B) {
	benchmarkHash(b, md5.New())
}

func BenchmarkSHA1(b *testing.B) {
	benchmarkHash(b, sha1.New())
}

func BenchmarkSHA256(b *testing.B) {
	benchmarkHash(b, sha256.New())
}

func BenchmarkSHA512(b *testing.B) {
	benchmarkHash(b, sha512.New())
}

func BenchmarkSHA3256(b *testing.B) {
	benchmarkHash(b, sha3.New256())
}

func BenchmarkSHA3512(b *testing.B) {
	benchmarkHash(b, sha3.New512())
}

func BenchmarkBLAKE2b256(b *testing.B) {
	h, _ := blake2b.New256(nil)
	benchmarkHash(b, h)
}

func BenchmarkBLAKE2b512(b *testing.B) {
	h, _ := blake2b.New512(nil)
	benchmarkHash(b, h)
}Copy the code
$go test-bench =. -benchmem BenchmarkMD5-4 1,000,000 1,783 ns/op 16 B/op 1 Allocs /op BenchmarkSHA1 1,000,000 1,504 Ns /op 32 B/ OP 1 ALlocs/OP benchmarkSHA256-4 500,000 3,201 NS/OP 32 B/ OP 1 Allocs/OP benchmarkSHA512-4 500,000 2,596 Ns/OP 64 B/ OP 1 ALLOCs/OP benchmarkSHA3256-4 300,000 4,485 NS/OP 512 B/ OP 3 Allocs/OP benchmarkSha3512-4 200,000 7,722 Ns/OP 576 B/ OP 3 ALlocs/OP benchmarkBlake2B256-4 1,000,000 1,311 NS/OP 32 B/ OP 1 Allocs/OP benchmarkBlake2B512-4 1,000,000 1,260 ns/op 64 B/op 1 ALLOCs /opCopy the code

Base64

This benchmark evaluates the performance of Base64 encoding and decoding using the Go encoding/base64 package on one kilobyte data.

package main import ( "encoding/base64" "math/rand" "testing" ) func BenchmarkEncode(b *testing.B) { data := make([]byte, 1024) rand.Read(data) b.ResetTimer() for n := 0; n < b.N; n++ { base64.StdEncoding.EncodeToString([]byte(data)) } } func BenchmarkDecode(b *testing.B) { data := make([]byte, 1024) rand.Read(data) encoded := base64.StdEncoding.EncodeToString([]byte(data)) b.ResetTimer() for n := 0; n < b.N; n++ { _, err := base64.StdEncoding.DecodeString(encoded) if err ! = nil { panic(err) } } }Copy the code
$ go test -bench=. -benchmem

BenchmarkEncode-4  1,000,000  1,876 ns/op  2,816 B/op  2 allocs/op
BenchmarkDecode-4    500,000  2,957 ns/op  2,560 B/op  2 allocs/op

Copy the code

Serialization

This benchmark evaluates the performance of serialization and deserialization using the json, protobuf, msgp and gob packages. The Protocol Buffers and the MessagePack types need to be generated first.

package main import ( "bytes" "encoding/gob" "encoding/json" "github.com/golang/protobuf/proto" "io/ioutil" "testing" ) type Book struct { Title string `json:"title"` Author string `json:"author"` Pages int `json:"num_pages"` Chapters []string `json:"chapters"` } /* syntax = "proto2"; package main; message BookProto { required string title = 1; required string author = 2; optional int64 pages = 3; repeated string chapters = 4; } */ // protoc --go_out=. book.proto /* //go:generate msgp -tests=false type BookDef struct { Title string `msg:"title"`  Author string `msg:"author"` Pages int `msg:"num_pages"` Chapters []string `msg:"chapters"` } */ // go generate func generateObject() *Book { return &Book{ Title: "The Art of Computer Programming, Vol. 2", Author: "Donald E. Knuth", Pages: 784, Chapters: []string{"Random numbers", "Arithmetic"}, } } func generateMessagePackObject() *BookDef { obj := generateObject() return &BookDef{ Title: obj.Title, Author: obj.Author, Pages: obj.Pages, Chapters: obj.Chapters, } } func generateProtoBufObject() *BookProto { obj := generateObject() return &BookProto{ Title: proto.String(obj.Title), Author: proto.String(obj.Author), Pages: proto.Int64(int64(obj.Pages)), Chapters: obj.Chapters, } } func BenchmarkJSONMarshal(b *testing.B) { obj := generateObject() b.ResetTimer() for n := 0; n < b.N; n++ { _, err := json.Marshal(obj) if err ! = nil { panic(err) } } } func BenchmarkJSONUnmarshal(b *testing.B) { out, err := json.Marshal(generateObject()) if err ! = nil { panic(err) } obj := &Book{} b.ResetTimer() for n := 0; n < b.N; n++ { err = json.Unmarshal(out, obj) if err ! = nil { panic(err) } } } func BenchmarkProtoBufMarshal(b *testing.B) { obj := generateProtoBufObject() b.ResetTimer() for n := 0; n < b.N; n++ { _, err := proto.Marshal(obj) if err ! = nil { panic(err) } } } func BenchmarkProtoBufUnmarshal(b *testing.B) { out, err := proto.Marshal(generateProtoBufObject()) if err ! = nil { panic(err) } obj := &BookProto{} b.ResetTimer() for n := 0; n < b.N; n++ { err = proto.Unmarshal(out, obj) if err ! = nil { panic(err) } } } func BenchmarkMessagePackMarshal(b *testing.B) { obj := generateMessagePackObject() b.ResetTimer() for n := 0; n < b.N; n++ { _, err := obj.MarshalMsg(nil) if err ! = nil { panic(err) } } } func BenchmarkMessagePackUnmarshal(b *testing.B) { obj := generateMessagePackObject() msg, err := obj.MarshalMsg(nil) if err ! = nil { panic(err) } obj = &BookDef{} b.ResetTimer() for n := 0; n < b.N; n++ { _, err = obj.UnmarshalMsg(msg) if err ! = nil { panic(err) } } } func BenchmarkGobMarshal(b *testing.B) { obj := generateObject() enc := gob.NewEncoder(ioutil.Discard) b.ResetTimer() for n := 0; n < b.N; n++ { err := enc.Encode(obj) if err ! = nil { panic(err) } } } func BenchmarkGobUnmarshal(b *testing.B) { obj := generateObject() var buf bytes.Buffer enc := gob.NewEncoder(&buf) err := enc.Encode(obj) if err ! = nil { panic(err) } for n := 0; n < b.N; n++ { err = enc.Encode(obj) if err ! = nil { panic(err) } } dec := gob.NewDecoder(&buf) b.ResetTimer() for n := 0; n < b.N; n++ { err = dec.Decode(&Book{}) if err ! = nil { panic(err) } } }Copy the code
$go test-bench =. -benchmem BenchmarkJSONMarshal-4 1,000,000 ns/op 640 B/op 3 allocs/op BenchmarkJSONUnmarshal-4 500,000 3,249 ns/ OP 432 B/ OP 8 Allocs/OP BenchmarkProtoBufMarshal-4 3,000,000 504 ns/ OP 552 B/ OP 5 Allocs /op BenchmarkProtoBufUnmarshal - 4, 2000000, 692 ns/op 432 B/op 10 allocs/op BenchmarkMessagePackMarshal - 4, 10000000, 134 Ns/op 160 B/op 1 allocs/op BenchmarkMessagePackUnmarshal - 4, 5000000, 252 ns/op 112 B / 4 allocs op/op BenchmarkGobMarshal-4 2,000,000 737 NS/OP 32 B/ OP 1 Allocs/OP BenchmarkGobUnmarshal-4 1,000,000 1,005 ns/op 272 B/op 8 allocs/opCopy the code

Compression

This benchmark evaluates the performance of compressing and decompressing 100 KB JSON data using the Go compress/gzip package.

package main import ( "bytes" "compress/gzip" "io/ioutil" "testing" ) func BenchmarkWrite(b *testing.B) { data, err := ioutil.ReadFile("test.json") if err ! = nil { panic(err) } zw := gzip.NewWriter(ioutil.Discard) b.ResetTimer() for n := 0; n < b.N; n++ { _, err = zw.Write(data) if err ! = nil { panic(err) } } } func BenchmarkRead(b *testing.B) { data, err := ioutil.ReadFile("test.json") if err ! = nil { panic(err) } var buf bytes.Buffer zw := gzip.NewWriter(&buf) _, err = zw.Write(data) if err ! = nil { panic(err) } err = zw.Close() if err ! = nil { panic(err) } r := bytes.NewReader(buf.Bytes()) zr, _ := gzip.NewReader(r) b.ResetTimer() for n := 0; n < b.N; n++ { r.Reset(buf.Bytes()) zr.Reset(r) _, err := ioutil.ReadAll(zr) if err ! = nil { panic(err) } } }Copy the code
$ go test -bench=. -benchmem

BenchmarkWrite-4    500  2,869,299 ns/op    1,627 B/op   0 allocs/op
BenchmarkRead-4   2,000    748,719 ns/op  261,088 B/op  22 allocs/op

Copy the code

URL Parsing

This benchmark evaluates the performance of URL parsing using the Go net/url package.

package main import ( "net/url" "testing" ) func BenchmarkParse(b *testing.B) { testUrl := "Https://www.example.com/path/file.html?param1=value1 ¶ m2 = 123" b.R esetTimer () for n: = 0; n < b.N; n++ { _, err := url.Parse(testUrl) if err ! = nil { panic(err) } } }Copy the code
$go test-bench =. -benchmem BenchmarkParse-4 3,000,000 413 ns/op 128 B/op 1 allocs/opCopy the code

Templates

This benchmark evaluates the performance of template execution using the Go text/template package.

package main import ( "io/ioutil" "testing" "text/template" ) var bookTemplate string = ` Title: {{.Title}}, Author: {{.Author}} {{ if .Pages}} Number of pages: {{ .Pages }}. {{ end }} {{ range .Chapters }} {{ . }}, {{ end }} ` type Book struct { Title string `json:"title"` Author string `json:"author"` Pages int `json:"num_pages"` Chapters []string `json:"chapters"` } var book *Book = &Book{ Title: "The Art of Computer Programming, Vol. 3", Author: "Donald E. Knuth", Pages: 800, Chapters: []string{"Sorting", "Searching"}, } func BenchmarkExecute(b *testing.B) { t := template.Must(template.New("book").Parse(bookTemplate)) for n := 0; n < b.N; n++ { err := t.Execute(ioutil.Discard, book) if err ! = nil { panic(err) } } }Copy the code
$go test-bench =. -benchmem BenchmarkExecute-4 500000,986 ns/op 168 B/op 12 allocs/opCopy the code

HTTP Server

This benchmark evaluates the performance of HTTP and HTTPS local round trips using the default ServeMux from the Go net/http package.

package main import ( "crypto/tls" "io/ioutil" "net" "net/http" "testing" ) var httpServer *http.Server var httpsServer *http.Server type testHandler struct { } func (th *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("OK.\n")) } func startHTTPServer() { if httpServer ! = nil { return } httpServer = &http.Server{ Handler: &testHandler{}, } listener, err := net.Listen("tcp", ":8080") if err ! = nil { panic(err) } go func() { err := httpServer.Serve(listener) if err ! = nil { panic(err) } }() } func startHTTPSServer() { if httpsServer ! = nil { return } httpsServer = &http.Server{ Handler: &testHandler{}, } listener, err := net.Listen("tcp", ":8443") if err ! = nil { panic(err) } go func() { err := httpServer.ServeTLS(listener, "server.crt", "server.key") if err ! = nil { panic(err) } }() } func sendRequest(client *http.Client, addr string) { res, err := client.Get(addr) if err ! = nil { panic(err) } if res.StatusCode ! = 200 { panic("request failed") } _, err = ioutil.ReadAll(res.Body) if err ! = nil { panic(err) } err = res.Body.Close() if err ! = nil { panic(err) } } func BenchmarkHTTP(b *testing.B) { startHTTPServer() client := &http.Client{} b.ResetTimer() for n := 0; n < b.N; n++ { sendRequest(client, "http://127.0.0.1:8080/")}} func BenchmarkHTTPNoKeepAlive(b * testing.b) {startHTTPServer() client := & http.client { Transport: &http.Transport{ DisableKeepAlives: true, }, } b.ResetTimer() for n := 0; n < b.N; n++ { sendRequest(client, "Http://127.0.0.1:8080/")}} func BenchmarkHTTPSNoKeepAlive (b * testing. B) {startHTTPSServer () client: HTTP. = & client { Transport: &http.Transport{ DisableKeepAlives: true, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, } b.ResetTimer() for n := 0; n < b.N; N++ {the sendRequest (client, "https://127.0.0.1:8443/")}}Copy the code
$go test-bench =. -benchmem BenchmarkHTTP-4 10,000 189,912 ns/op 5,736 B/op 70 Allocs /op BenchmarkHTTPNoKeepAlive-4 359027 ns/op 17204 B / 5000 op 123 allocs/op BenchmarkHTTPSNoKeepAlive - 4, 300, 4052008 ns/op 116289 B / 843 allocs op/opCopy the code