<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一個 Benchmark 比較分析工具

          共 423字,需瀏覽 1分鐘

           ·

          2022-05-29 11:32

          點(diǎn)擊上方“Go語言進(jìn)階學(xué)習(xí)”,進(jìn)行關(guān)注

          回復(fù)“Go語言”即可獲贈從入門到進(jìn)階共10本電子書

          有弟皆分散,無家問死生。

          在 Go 中,通過撰寫 Benchmark 函數(shù)可以很方便地對某個功能點(diǎn)進(jìn)行性能檢測。對于重要的函數(shù),我們可以在 CI/CD 中添加相應(yīng)的測試流程,當(dāng)函數(shù)性能發(fā)生變化時能夠及時感知。那問題來了,如何檢測函數(shù)的性能變化?

          換個說法,你編寫了某功能函數(shù)但發(fā)現(xiàn)它運(yùn)行很慢,需要對該函數(shù)進(jìn)行優(yōu)化,當(dāng)你在谷歌搜索找到更好的實(shí)現(xiàn)方式,通過 Benchmark 函數(shù)發(fā)現(xiàn)它的確變快了。但你說不清楚具體變快了多少,你想知道函數(shù)優(yōu)化前后的性能對比,提高多少百分點(diǎn),可信度高嗎?

          針對以上的需求場景,有一個工具可以幫助到你,它就是 benchstat。

          Benchmark 示例

          我們先回顧一下基準(zhǔn)測試。為了方便理解,這里以計(jì)算經(jīng)典的計(jì)算斐波那契數(shù)列值為例。

          func?FibSolution(n?int)?int?{
          ?if?n?2?{
          ??return?n
          ?}

          ?return?FibSolution(n-1)?+?FibSolution(n-2)
          }

          上述代碼是遞歸式實(shí)現(xiàn),很明顯,當(dāng) n 越來越大時,該函數(shù)的運(yùn)行會變得非常耗時。以 n 為 20 為例,Benchmark 函數(shù)如下

          func?BenchmarkFib20(b?*testing.B)?{
          ?for?i?:=?0;?i???FibSolution(20)
          ?}
          }

          命令行執(zhí)行go test -bench=BenchmarkFib20得到性能結(jié)果

          BenchmarkFib20-8???????????39452?????????????30229?ns/op

          其中,-8 代表的是 8 cpu,函數(shù)運(yùn)行次數(shù)為 39452,每次函數(shù)的平均花費(fèi)時間為 30229ns。如果我們想得到多次樣本數(shù)據(jù),可以指定 go test 的 -count=N 參數(shù)。例如想得到 5 次樣本數(shù)據(jù),則執(zhí)行go test -bench=BenchmarkFib20 -count=5

          BenchmarkFib20-8???????????39325?????????????30297?ns/op
          BenchmarkFib20-8???????????39216?????????????30349?ns/op
          BenchmarkFib20-8???????????39901?????????????30251?ns/op
          BenchmarkFib20-8???????????39336?????????????30455?ns/op
          BenchmarkFib20-8???????????39423?????????????30894?ns/op

          計(jì)算斐波那契數(shù)列值的迭代式實(shí)現(xiàn)如下

          func?FibSolution(n?int)?int?{
          ?if?n?2?{
          ??return?n
          ?}
          ?p,?q,?r?:=?0,?0,?1
          ?for?i?:=?2;?i?<=?n;?i++?{
          ??p?=?q
          ??q?=?r
          ??r?=?p?+?q
          ?}
          ?return?r
          }

          對比這兩種函數(shù)的性能差異,最樸素的方式就是分別對這兩個函數(shù)進(jìn)行基準(zhǔn)測試,然后通過手工分析這些基準(zhǔn)測試結(jié)果,但是這并不直觀。

          benchstat

          benchstat 是 Go 官方推薦的一款命令行工具,它用于計(jì)算和比較基準(zhǔn)測試的相關(guān)統(tǒng)計(jì)數(shù)據(jù)。

          我們可以通過以下命令進(jìn)行安裝

          go?install?golang.org/x/perf/cmd/benchstat@latest

          執(zhí)行 -h 參數(shù)可以看到該工具的使用描述

          ~?$?benchstat?-h
          usage:?benchstat?[options]?old.txt?[new.txt]?[more.txt?...]
          options:
          ??-alpha?α
          ?????consider?change?significant?if?p???-csv
          ?????print?results?in?CSV?form
          ??-delta-test?test
          ?????significance?test?to?apply?to?delta:?utest,?ttest,?or?none?(default?"utest")
          ??-geomean
          ?????print?the?geometric?mean?of?each?file
          ??-html
          ?????print?results?as?an?HTML?table
          ??-norange
          ?????suppress?range?columns?(CSV?only)
          ??-sort?order
          ?????sort?by?order:?[-]delta,?[-]name,?none?(default?"none")
          ??-split?labels
          ?????split?benchmarks?by?labels?(default?"pkg,goos,goarch")

          我們想比較 FibSolution(n) 從 15 到 20,兩種實(shí)現(xiàn)方式的性能基準(zhǔn)測試。

          $?go?test?-bench=.?-count=5?|?tee?old.txt
          $?go?test?-bench=.?-count=5?|?tee?new.txt

          注意,這兩條命令執(zhí)行時,分別對應(yīng) FibSolution 函數(shù)采用遞歸式和迭代式實(shí)現(xiàn)邏輯。

          此時,我們可以對這兩個函數(shù)實(shí)現(xiàn)邏輯進(jìn)行性能對比

          ?$?benchstat?old.txt?new.txt?
          name?????old?time/op??new?time/op??delta
          Fib15-8??2.67μs?±?2%??0.01μs?±?5%??-99.81%??(p=0.008?n=5+5)
          Fib16-8??4.20μs?±?1%??0.01μs?±?2%??-99.87%??(p=0.008?n=5+5)
          Fib17-8??6.81μs?±?0%??0.01μs?±?2%??-99.92%??(p=0.008?n=5+5)
          Fib18-8??11.1μs?±?1%???0.0μs?±?1%??-99.95%??(p=0.008?n=5+5)
          Fib19-8??18.0μs?±?2%???0.0μs?±?4%??-99.97%??(p=0.008?n=5+5)
          Fib20-8??29.2μs?±?1%???0.0μs?±?3%??-99.98%??(p=0.008?n=5+5)

          可以看到,遞歸式實(shí)現(xiàn)的函數(shù),他的執(zhí)行時間隨著 n 值變大增加非常明顯。迭代式實(shí)現(xiàn)方式,相較于遞歸式,它的平均時間開銷降低了 99 % 以上,優(yōu)化效果非常明顯。

          另外,p=0.008 表示結(jié)果的可信程度,p 值越大表明可信度越低。一般以 0.05 作為臨界值,超過該值,則結(jié)果不可信。n=5+5 表示分別使用的有效樣本數(shù)量。

          總結(jié)

          benchstat 是一個基準(zhǔn)測試統(tǒng)計(jì)工具,當(dāng)我們做一些優(yōu)化工作時,可以利用它減輕人工分析數(shù)據(jù)成本。

          如果你的項(xiàng)目在 CI/CD 流程中有部署自動化測試,那不妨將該工具加入進(jìn)來。在對函數(shù)有改動且加劇了性能損耗時,它或許能幫助你提前發(fā)現(xiàn)問題。



          -------------------?End?-------------------

          往期精彩文章推薦:

          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入Go學(xué)習(xí)群請?jiān)诤笈_回復(fù)【入群

          萬水千山總是情,點(diǎn)個【在看】行不行

          瀏覽 32
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美亚州一二三区 | 免费成人毛片 | 日本在线视频精品 | 亚洲成人性爱影院 | 性少妇69 |