funcEmptyStructMap(n int) { m := make(map[int]struct{}) for i := 0; i < n; i++ { m[i] = struct{}{} } } funcBoolMap(n int) { m := make(map[int]bool) for i := 0; i < n; i++ { m[i] = false } }
1 2 3 4 5 6 7 8 9 10 11
funcBenchmarkEmptyStructMap(b *testing.B) { for i := 0; i < b.N; i++ { EmptyStructMap(100000000) } }
funcBenchmarkBoolMap(b *testing.B) { for i := 0; i < b.N; i++ { BoolMap(100000000) } }
执行结果:
1 2 3 4 5 6 7 8 9
$ go test -bench . goos: windows goarch: amd64 pkg: GoProject1 cpu: 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz BenchmarkEmptyStructMap-16 1 13943515100 ns/op BenchmarkBoolMap-16 1 14002905100 ns/op PASS ok GoProject1 28.215s
Used Connections: 100 Used Threads: 1 Total number of calls: 50000
===========================TIMINGS=========================== Total time passed: 22.95s Avg time per request: 45.76ms Requests per second: 2179.05 Median time per request: 45.14ms 99th percentile time: 53.77ms Slowest time for request: 119.00ms
=============================DATA============================= Total response body sizes: 251100000 Avg response body per request: 5022.00 Byte Transfer rate per second: 10943208.24 Byte/s (10.94 MByte/s) ==========================RESPONSES========================== 20X Responses: 50000 (100.00%) 30X Responses: 0 (0.00%) 40X Responses: 0 (0.00%) 50X Responses: 0 (0.00%) Errors: 0 (0.00%)
接着再开一个终端,以使用pprof来分析。
执行命令:
1
go tool pprof http://127.0.0.1:8080/debug/pprof/profile
执行上面的代码会进入交互界面如下:
1 2 3 4 5 6 7 8 9 10
(base) PS F:\GolandProjects\beegoProject\blob> go tool pprof http://127.0.0.1:8080/debug/pprof/profile Fetching profile over HTTP from http://127.0.0.1:8080/debug/pprof/profile Saved profile in C:\Users\19393\pprof\pprof.blob.exe.samples.cpu.004.pb.gz File: blob.exe Build ID: F:\GolandProjects\beegoProject\blob\blob.exe2023-08-01 16:06:16.7719208 +0800 CST Type: cpu Time: Aug 1, 2023 at 4:10pm (CST) Duration: 30s, Total samples = 44.41s (148.02%) Entering interactive mode (type "help" for commands, "o" for options) (pprof)
我们可以在交互界面输入top5来查看程序中占用CPU前5位的函数:
1 2 3 4 5 6 7 8 9 10
(pprof) top5 Showing nodes accounting for 27510ms, 61.95% of 44410ms total Dropped 859 nodes (cum <= 222.05ms) Showing top 5 nodes out of 246 flat flat% sum% cum cum% 21960ms 49.45% 49.45% 22080ms 49.72% runtime.cgocall 2010ms 4.53% 53.97% 5980ms 13.47% runtime.scanobject 1410ms 3.17% 57.15% 1740ms 3.92% runtime.greyobject 1340ms 3.02% 60.17% 1730ms 3.90% runtime.findObject 790ms 1.78% 61.95% 790ms 1.78% runtime.stdcall2
(pprof) list cgocall Total: 44.41s ROUTINE ======================== runtime.cgocall in F:\Users\19393\sdk\go1.20.4\src\runtime\cgocall.go 21.96s 22.08s (flat, cum) 49.72% of Total . . 123:func cgocall(fn, arg unsafe.Pointer) int32 { . . 124: if !iscgo && GOOS != "solaris" && GOOS != "illumos" && GOOS != "windows" { . . 125: throw("cgocall unavailable") . . 126: } . . 127: . . 128: if fn == nil { . . 129: throw("cgocall nil") . . 130: } . . 131: . . 132: if raceenabled { . . 133: racereleasemerge(unsafe.Pointer(&racecgosync)) . . 134: } . . 135: . . 136: mp := getg().m . . 137: mp.ncgocall++ . . 138: mp.ncgo++ . . 139: . . 140: // Reset traceback. . . 141: mp.cgoCallers[0] = 0 . . 142: . . 143: // Announce we are entering a system call . . 144: // so that the scheduler knows to create another . . 145: // M to run goroutines while we are in the . . 146: // foreign code. . . 147: // . . 148: // The call to asmcgocall is guaranteed not to . . 149: // grow the stack and does not allocate memory, . . 150: // so it is safe to call while "in a system call", outside . . 151: // the $GOMAXPROCS accounting. . . 152: // . . 153: // fn may call back into Go code, in which case we'll exit the . . 154: // "system call", run the Go code (which may grow the stack), . . 155: // and then re-enter the "system call" reusing the PC and SP . . 156: // saved by entersyscall here. 21.94s 21.94s 157: entersyscall() . . 158: . . 159: // Tell asynchronous preemption that we're entering external . . 168: . . 169: // Update accounting before exitsyscall because exitsyscall may . . 170: // reschedule us on to a different M. . . 171: mp.incgo = false . . 172: mp.ncgo-- . . 173: 20ms 40ms 174: osPreemptExtExit(mp) . . 175: . 100ms 176: exitsyscall() . . 177: . . 178: // Note that raceacquire must be called only after exitsyscall has . . 179: // wired this M to a P. . . 180: if raceenabled { . . 181: raceacquire(unsafe.Pointer(&racecgosync))
(base) PS F:\GolandProjects\beegoProject\blob> go tool pprof http://127.0.0.1:8080/debug/pprof/profile Fetching profile over HTTP from http://127.0.0.1:8080/debug/pprof/profile Saved profile in C:\Users\19393\pprof\pprof.blob.exe.samples.cpu.008.pb.gz File: blob.exe Build ID: F:\GolandProjects\beegoProject\blob\blob.exe2023-08-01 16:06:16.7719208 +0800 CST Type: cpu Time: Aug 1, 2023 at 7:02pm (CST) Duration: 30s, Total samples = 44.25s (147.48%) Entering interactive mode (type "help" for commands, "o" for options) (pprof) web (pprof)