??Go??????????????????
???????????? ???????[ 2017/6/12 11:42:02 ] ??????????????? ???????
?????????Щ?????????????????????????????1??????????????????????????????????顣
????д?????????Go?????????????go????????????????????????????????????Go????????????÷???????????????Benchmark??????
????benchmark
????Go??Benchmar???????′??????_test.go???????????????????溯????
????func BenchmarkStringJoin1(b *testing.B) {
????b.ReportAllocs()
????input := []string{"Hello"?? "World"}
????for i := 0; i < b.N; i++ {
????result := strings.Join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????????????????:
????# go test -run=xxx -bench=. -benchtime="3s" -cpuprofile profile_cpu.out
??????????????????????????????benchmark???????????cpu???????????.
??????????????:
????1. -benchtime ???????benchmark?????????
????2. b.ReportAllocs() ????report?а???????????????????????:
BenchmarkStringJoin1-4 300000 4351 ns/op 32 B/op 2 allocs/op
????-4???4??CPU?????У?300000???????????30??Σ?4531ns/op??????????к??4531????32B/op????????з?????32?????棻2 allocs/op????????з?????2?ζ???
????????????????????????????·?????????????????????
?????????????????????????????СС?????:
?? func BenchmarkStringJoin2(b *testing.B) {
????b.ReportAllocs()
????input := []string{"Hello"?? "World"}
????join := func(strs []string?? delim string) string {
????if len(strs) == 2 {
????return strs[0] + delim + strs[1];
????}
????return "";
????};
????for i := 0; i < b.N; i++ {
????result := join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
?????μ?Benchmark??????
????BenchmarkStringJoin2-4 500000 2440 ns/op 16 B/op 1 allocs/op
???????????????????????????????????????60%?????
????cpu profile
??????????benchmark??????????????????????????????????????ú?????????????????????????????????????????????Cpu Profile??????
????Cpu profile??Go??????????????????????????????????memory??block profile??????????????????????????????
????????benchmark?????????????profile_cpu.out?????????????????????????:
??# go tool pprof app.test profile_cpu.out
????Entering interactive mode (type "help" for commands)
????(pprof) top10
????8220ms of 10360ms total (79.34%)
????Dropped 63 nodes (cum <= 51.80ms)
????Showing top 10 nodes out of 54 (cum >= 160ms)
????flat flat% sum% cum cum%
????2410ms 23.26% 23.26% 4960ms 47.88% runtime.concatstrings
????2180ms 21.04% 44.31% 2680ms 25.87% runtime.mallocgc
????1200ms 11.58% 55.89% 1200ms 11.58% runtime.memmove
????530ms 5.12% 61.00% 530ms 5.12% runtime.memeqbody
????530ms 5.12% 66.12% 2540ms 24.52% runtime.rawstringtmp
????470ms 4.54% 70.66% 2420ms 23.36% strings.Join
????390ms 3.76% 74.42% 2330ms 22.49% app.BenchmarkStringJoin3B
????180ms 1.74% 76.16% 1970ms 19.02% runtime.rawstring
????170ms 1.64% 77.80% 5130ms 49.52% runtime.concatstring3
????160ms 1.54% 79.34% 160ms 1.54% runtime.eqstring
???????????????????????????????е?????·??????????????????????????????????????svg????pdf???
????# go tool pprof -svg profile_cpu.out > profile_cpu.svg
????# go tool pprof -pdf profile_cpu.out > profile_cpu.pdf
??????????profile_cpu.pdf???:
?????????????????????benchmark????(????????benmark?????????????????)????????????????????????benchmark?????????????
?? go test -run=xxx -bench=BenchmarkStringJoin2B$ -cpuprofile profile_2b.out
????go test -run=xxx -bench=BenchmarkStringJoin2$ -cpuprofile profile_2.out
????go tool pprof -svg profile_2b.out > profile_2b.svg
????go tool pprof -svg profile_2.out > profile_2.svg
??????????????benchmark????????(??????????)runtime.concatstrings???????????????????????????????????????????????????????????????????flame graphs ???
????“A flame graph is a good way to drill down your benchmarks?? finding your bottlenecks #golang” via @TitPetric
?????????????????????????Щ???ο?á?
??????????Щ?????????? uber/go-torch???????????????https://github.com/brendangregg/FlameGraph???????????????????????????????frame graph?????????????????????????????
????#!/bin/bash
????# install flamegraph scripts
????if [ ! -d "/opt/flamegraph" ]; then
????echo "Installing flamegraph (git clone)"
????git clone --depth=1 https://github.com/brendangregg/FlameGraph.git /opt/flamegraph
????fi
????# install go-torch using docker
????if [ ! -f "bin/go-torch" ]; then
????echo "Installing go-torch via docker"
????docker run --net=party --rm=true -it -v $(pwd)/bin:/go/bin golang go get github.com/uber/go-torch
????# or if you have go installed locally: go get github.com/uber/go-torch
????fi
????PATH="$PATH:/opt/flamegraph"
????bin/go-torch -b profile_cpu.out -f profile_cpu.torch.svg
??????????????benchmark?·?????????????????????cpu profile????????????benchmark?У????????????debug????????????????????????????????????к?????????????? ???????????????benchmark????
package main
????import "testing"
????import "strings"
????func BenchmarkStringJoin1(b *testing.B) {
????b.ReportAllocs()
????input := []string{"Hello"?? "World"}
????for i := 0; i < b.N; i++ {
????result := strings.Join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????func BenchmarkStringJoin1B(b *testing.B) {
????b.ReportAllocs()
????for i := 0; i < b.N; i++ {
????input := []string{"Hello"?? "World"}
????result := strings.Join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????func BenchmarkStringJoin2(b *testing.B) {
????b.ReportAllocs()
????input := []string{"Hello"?? "World"}
????join := func(strs []string?? delim string) string {
????if len(strs) == 2 {
????return strs[0] + delim + strs[1];
????}
????return "";
????};
????for i := 0; i < b.N; i++ {
????result := join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????func BenchmarkStringJoin2B(b *testing.B) {
????b.ReportAllocs()
????join := func(strs []string?? delim string) string {
????if len(strs) == 2 {
????return strs[0] + delim + strs[1];
????}
????return "";
????};
????for i := 0; i < b.N; i++ {
????input := []string{"Hello"?? "World"}
????result := join(input?? " ")
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????func BenchmarkStringJoin3(b *testing.B) {
????b.ReportAllocs()
????input := []string{"Hello"?? "World"}
????for i := 0; i < b.N; i++ {
????result := input[0] + " " + input[1];
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
????func BenchmarkStringJoin3B(b *testing.B) {
????b.ReportAllocs()
????for i := 0; i < b.N; i++ {
????input := []string{"Hello"?? "World"}
????result := input[0] + " " + input[1];
????if result != "Hello World" {
????b.Error("Unexpected result: " + result)
????}
????}
????}
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11