1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Golang基準(zhǔn)測試

        共 15152字,需瀏覽 31分鐘

         ·

        2021-08-23 21:34

        目錄

        • 1、基本使用

        • 2、bench 的工作原理

        • 3、傳入 cpu num 進行測試

        • 4、count 多次運行基準(zhǔn)測試

        • 5、benchtime 指定運行秒數(shù)

        • 6、ResetTimer 重置定時器

        • 7、benchmem 展示內(nèi)存消耗


        1、基本使用

        基準(zhǔn)測試常用于代碼性能測試,函數(shù)需要導(dǎo)入testing包,并定義以Benchmark開頭的函數(shù), 參數(shù)為testing.B指針類型,在測試函數(shù)中循環(huán)調(diào)用函數(shù)多次

        go test testcalc/calc -bench .
        go test testcalc/calc -bench . -run=none
        # 顯示內(nèi)存信息
        go test testcalc/calc -bench . -benchmem
        go test -bench=. -benchmem -run=none

        go test會在運行基準(zhǔn)測試之前之前執(zhí)行包里所有的單元測試,所有如果你的包里有很多單元測試,或者它們會運行很長時間,你也可以通過go test-run標(biāo)識排除這些單元測試

        業(yè)務(wù)代碼fib.go,測試斐波那契數(shù)列

        package pkg06

        func fib(n int) int {
         if n == 0 || n == 1 {
          return n
         }
         return fib(n-2) + fib(n-1)
        }

        測試代碼fib_test.go

        package pkg06

        import "testing"

        func BenchmarkFib(b *testing.B) {
         for n := 0; n < b.N; n++ {
          fib(30)
         }
        }

        執(zhí)行測試

        ?  go test -bench=. -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib-12              250           4682682 ns/op
        PASS
        ok      pkg06   1.875s
        ?  go test -bench=. -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib-12              249           4686452 ns/op               0 B/op          0 allocs/op
        PASS
        ok      pkg06   1.854s

        2、bench 的工作原理

        • 基準(zhǔn)測試函數(shù)會被一直調(diào)用直到b.N無效,它是基準(zhǔn)測試循環(huán)的次數(shù)
        • b.N1開始,如果基準(zhǔn)測試函數(shù)在1秒內(nèi)就完成 (默認值),則b.N增加,并再次運行基準(zhǔn)測試函數(shù)
        • b.N的值會按照序列1,2,5,10,20,50,...增加,同時再次運行基準(zhǔn)測測試函數(shù)
        • 上述結(jié)果解讀代表1秒內(nèi)運行了250次,每次4682682 ns
        • -12后綴和用于運行次測試的GOMAXPROCS值有關(guān)。與GOMAXPROCS一樣,此數(shù)字默認為啟動時Go進程可見的CPU數(shù)??梢允褂?code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(150, 84, 181);">-cpu標(biāo)識更改此值,可以傳入多個值以列表形式來運行基準(zhǔn)測試

        3、傳入 cpu num 進行測試

        ?  go test -bench=. -cpu=1,2,4  -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib                 244           4694667 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-2               255           4721201 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-4               256           4756392 ns/op               0 B/op          0 allocs/op
        PASS
        ok      pkg06   5.826s

        4、count 多次運行基準(zhǔn)測試

        因為熱縮放、內(nèi)存局部性、后臺處理、gc活動等等會導(dǎo)致單次的誤差,所以一般會進行多次測試

        ?  go test -bench=. -count=10  -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib-12              217           5993577 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              246           5065577 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              244           4955397 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              255           4689529 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              254           4879802 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              254           4691213 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              255           4772108 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              240           4724141 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              255           4717087 ns/op               0 B/op          0 allocs/op
        BenchmarkFib-12              255           4787803 ns/op               0 B/op          0 allocs/op
        PASS
        ok      pkg06   18.166s

        5、benchtime 指定運行秒數(shù)

        有的函數(shù)比較慢,為了更精確的結(jié)果,可以通過-benchtime標(biāo)志指定運行時間,從而使它運行更多次

        ?  go test -bench=. -benchtime=5s  -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib-12             1128           4716535 ns/op               0 B/op          0 allocs/op
        PASS
        ok      pkg06   7.199s

        6、ResetTimer 重置定時器

        可能在真正測試之前還需要做很多例如初始化等工作,這時可以在需要測試的函數(shù)執(zhí)行之初添加一個重置定時器的功能,這樣最終得到的時間就更為精確

        package pkg06

        import (
         "testing"
         "time"
        )

        func BenchmarkFib(b *testing.B) {
         time.Sleep(3 * time.Second)
         b.ResetTimer()
         for n := 0; n < b.N; n++ {
          fib(30)
         }
        }

        執(zhí)行測試

        ?  go test -bench=. -benchtime=5s  -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg06
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkFib-12             1239           4712413 ns/op               0 B/op          0 allocs/op
        PASS
        ok      pkg06   16.122s

        7、benchmem 展示內(nèi)存消耗

        • 例如測試大cap的切片,直接用cap初始化和cap動態(tài)擴容進行對比
        package pkg07

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

        // 指定大的cap的切片
        func generateWithCap(n int) []int {
         rand.Seed(time.Now().UnixNano())
         nums := make([]int0, n)
         for i := 0; i < n; i++ {
          nums = append(nums, rand.Int())
         }
         return nums
        }

        // 動態(tài)擴容的slice
        func generateDynamic(n int) []int {
         rand.Seed(time.Now().UnixNano())
         nums := make([]int0)
         for i := 0; i < n; i++ {
          nums = append(nums, rand.Int())
         }
         return nums
        }

        func BenchmarkGenerateWithCap(b *testing.B) {
         for n := 0; n < b.N; n++ {
          generateWithCap(100000)
         }
        }

        func BenchmarkGenerateDynamic(b *testing.B) {
         for n := 0; n < b.N; n++ {
          generateDynamic(100000)
         }
        }

        執(zhí)行測試

        ?  go test -bench=. -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg07
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkGenerateWithCap-12          672           1729465 ns/op          802817 B/op          1 allocs/op
        BenchmarkGenerateDynamic-12          561           2122992 ns/op         4654346 B/op         30 allocs/op
        PASS
        ok      pkg07   3.777s

        結(jié)論:用cap初始化好的性能可以高一個數(shù)據(jù)量級

        • 例如測試測試函數(shù)復(fù)雜度,不帶capslice動態(tài)擴容

        對上面代碼中調(diào)用動態(tài)擴容生成切片進行再次封裝

        package pkg08

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

        // 指定大的cap的切片
        func generateWithCap(n int) []int {
         rand.Seed(time.Now().UnixNano())
         nums := make([]int0, n)
         for i := 0; i < n; i++ {
          nums = append(nums, rand.Int())
         }
         return nums
        }

        // 動態(tài)擴容的slice
        func generateDynamic(n int) []int {
         rand.Seed(time.Now().UnixNano())
         nums := make([]int0)
         for i := 0; i < n; i++ {
          nums = append(nums, rand.Int())
         }
         return nums
        }

        func benchmarkGenerate(i int, b *testing.B) {
         for n := 0; n < b.N; n++ {
          generateDynamic(i)
         }
        }

        func BenchmarkGenerateDynamic1000(b *testing.B)     { benchmarkGenerate(1000, b) }
        func BenchmarkGenerateDynamic10000(b *testing.B)    { benchmarkGenerate(10000, b) }
        func BenchmarkGenerateDynamic100000(b *testing.B)   { benchmarkGenerate(100000, b) }
        func BenchmarkGenerateDynamic1000000(b *testing.B)  { benchmarkGenerate(1000000, b) }
        func BenchmarkGenerateDynamic10000000(b *testing.B) { benchmarkGenerate(10000000, b) }

        執(zhí)行測試

        ?  go test -bench=. -benchmem -run=none
        goos: darwin
        goarch: amd64
        pkg: pkg08
        cpu: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
        BenchmarkGenerateDynamic1000-12            39540             26557 ns/op           16376 B/op         11 allocs/op
        BenchmarkGenerateDynamic10000-12            5452            210894 ns/op          386296 B/op         20 allocs/op
        BenchmarkGenerateDynamic100000-12            572           2106325 ns/op         4654341 B/op         30 allocs/op
        BenchmarkGenerateDynamic1000000-12            48          23070939 ns/op        45188416 B/op         40 allocs/op
        BenchmarkGenerateDynamic10000000-12            5         212567041 ns/op        423503110 B/op        50 allocs/op
        PASS
        ok      pkg08   9.686s

        結(jié)論:輸入變?yōu)樵瓉淼?code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(150, 84, 181);">10倍,單次耗時也差不多是上一級的10倍。說明這個函數(shù)的復(fù)雜度是接近線性的

        See you ~

        瀏覽 34
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲日韩精品电影 | 日本超碰| 日韩欧美国产电影一区二区三区 | 区一区二区三视频 | 韩国面膜胸口一面膜下的作用 | 久久免费视频一区二区三区 | 护士脱了裙子坐上去好爽 | 影音先锋新男人av资源网站 | 男人舔女人下面高潮 | 女超人h版成c人版在线观看 |