中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言之基準測試

發布時間:2020-08-04 04:06:14 來源:網絡 閱讀:446 作者:baby神 欄目:編程語言
什么是基準測試


基準測試,是一種測試代碼性能的方法,比如你有多種不同的方案,都可以解決問題,那么到底是那種方案性能更好呢?這時候基準測試就派上用場了。


基準測試主要是通過測試CPU和內存的效率問題,來評估被測試代碼的性能,進而找到更好的解決方案。比如鏈接池的數量不是越多越好,那么哪個值才是最優值呢,這就需要配合基準測試不斷調優了。


如何編寫基準測試


基準測試代碼的編寫和單元測試非常相似,它也有一定的規則,我們先看一個示例。


itoa_test.go


func BenchmarkSprintf(b *testing.B){
    num:=10
    b.ResetTimer()
    for i:=0;i<b.N;i++{
        fmt.Sprintf("%d",num)
    }
}


這是一個基準測試的例子,從中我們可以看出以下規則:


  • 基準測試的代碼文件必須以_test.go結尾。


  • 基準測試的函數必須以Benchmark開頭,必須是可導出的。


  • 基準測試函數必須接受一個指向Benchmark類型的指針作為唯一參數。


  • 基準測試函數不能有返回值。


  • b.ResetTimer是重置計時器,這樣可以避免for循環之前的初始化代碼的干擾。


  • 最后的for循環很重要,被測試的代碼要放到循環里。


  • b.N是基準測試框架提供的,表示循環的次數,因為需要反復調用測試的代碼,才可以評估性能。


下面我們運行下基準測試,看看效果。


?  hello go test -bench=. -run=none
BenchmarkSprintf-8      20000000               117 ns/op PASS ok      flysnow.org/hello       2.474s


運行基準測試也要使用go test命令,不過我們要加上-bench=標記,它接受一個表達式作為參數,匹配基準測試的函數,.表示運行所有基準測試。


因為默認情況下go test會運行單元測試,為了防止單元測試的輸出影響我們查看基準測試的結果,可以使用-run=匹配一個從來沒有的單元測試方法,過濾掉單元測試的輸出,我們這里使用none,因為我們基本上不會創建這個名字的單元測試方法。


下面著重解釋下說出的結果,看到函數后面的-8了嗎?這個表示運行時對應的GOMAXPROCS的值。接著的20000000表示運行for循環的次數,也就是調用被測試代碼的次數,最后的117 ns/op表示每次需要話費 117 納秒。


以上是測試時間默認是 1 秒,也就是 1 秒的時間,調用兩千萬次,每次調用花費 117 納秒。如果想讓測試運行的時間更長,可以通過-benchtime指定,比如 3 秒。


?  hello go test -bench=. -benchtime=3s -run=none
BenchmarkSprintf-8      50000000               109 ns/op PASS ok      flysnow.org/hello       5.628s


可以發現,我們加長了測試時間,測試的次數變多了,但是最終的性能結果:每次執行的時間,并沒有太大變化。一般來說這個值最好不要超過3秒,意義不大。


性能對比


上面那個基準測試的例子,其實是一個int類型轉為string類型的例子,標準庫里還有幾種方法,我們看下哪種性能更加。


func BenchmarkSprintf(b *testing.B){
    num:=10
    b.ResetTimer()
    for i:=0;i<b.N;i++{
        fmt.Sprintf("%d",num)
    }}func BenchmarkFormat(b *testing.B){
    num:=int64(10)
    b.ResetTimer()
    for i:=0;i<b.N;i++{
        strconv.FormatInt(num,10)
    }}func BenchmarkItoa(b *testing.B){
    num:=10
    b.ResetTimer()    
    for i:=0;i<b.N;i++{
        strconv.Itoa(num)
    }
}


運行基準測試,看看結果:


?  hello go test -bench=. -run=none              BenchmarkSprintf-8      20000000               117 ns/op
BenchmarkFormat-8       50000000                33.3 ns/op
BenchmarkItoa-8         50000000                34.9 ns/op PASS ok      flysnow.org/hello       5.951s


從結果上看strconv.FormatInt函數是最快的,其次是strconv.Itoa,然后是fmt.Sprintf最慢,前兩個函數性能達到了最后一個的 3 倍多。那么最后一個為什么這么慢的,我們再通過-benchmem找到根本原因。


?  hello go test -bench=. -benchmem -run=none
BenchmarkSprintf-8      20000000       110 ns/op      16 B/op      2 allocs/op
BenchmarkFormat-8       50000000       31.0 ns/op     2 B/op       1 allocs/op
BenchmarkItoa-8         50000000       33.1 ns/op     2 B/op       1 allocs/op PASS ok      flysnow.org/hello       5.610s


-benchmem可以提供每次操作分配內存的次數,以及每次操作分配的字節數。從結果我們可以看到,性能高的兩個函數,每次操作都是進行 1 次內存分配,而最慢的那個要分配 2 次;性能高的每次操作分配 2 個字節內存,而慢的那個函數每次需要分配 16 字節的內存。從這個數據我們就知道它為什么這么慢了,內存分配都占用都太高。


在代碼開發中,對于我們要求性能的地方,編寫基準測試非常重要,這有助于我們開發出性能更好的代碼。不過性能、可用性、復用性等也要有一個相對的取舍,不能為了追求性能而過度優化。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

旺苍县| 阿图什市| 益阳市| 平潭县| 齐齐哈尔市| 松溪县| 平度市| 郴州市| 藁城市| 凌云县| 顺义区| 遂宁市| 昭通市| 饶河县| 阿合奇县| 资溪县| 清涧县| 阿拉善左旗| 尼勒克县| 霍林郭勒市| 尉氏县| 醴陵市| 景德镇市| 日照市| 嘉鱼县| 淄博市| 洪泽县| 广昌县| 梅河口市| 尚义县| 海原县| 惠水县| 防城港市| 凤庆县| 集贤县| 新闻| 锦屏县| 抚州市| 海晏县| 佳木斯市| 渭南市|