最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言如何實(shí)現(xiàn)Benchmark函數(shù)

 更新時(shí)間:2024年12月25日 11:09:23   作者:AnthonyDong  
go想要在main函數(shù)中測(cè)試benchmark會(huì)麻煩一些,所以這篇文章主要為大家介紹了如何實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的且沒(méi)有開(kāi)銷(xiāo)的benchmark函數(shù),希望對(duì)大家有所幫助

背景

go 必須要 test 才能跑benchmark,導(dǎo)致一些情況下想要在main函數(shù)中測(cè)試benchmark會(huì)麻煩一些,因此我實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的且沒(méi)有開(kāi)銷(xiāo)的benchmark函數(shù),方便使用!其次也方便大家學(xué)習(xí)下如何實(shí)現(xiàn)一個(gè)零開(kāi)銷(xiāo)的benchmark框架!

benchamrk 實(shí)現(xiàn)

對(duì)于有timeout的benchamrk,每次都去比較 time.Before(timeout) 開(kāi)銷(xiāo)非常的大,而且 benchmark 的對(duì)外函數(shù)也不能是一個(gè)空函數(shù)一定要帶 count ,因?yàn)楹瘮?shù)調(diào)用大概會(huì)劣化 ns 級(jí)別!

所以一般的benchmark算法都是梯度benchmark,即 1,10,100,1000,10000,100000,1000000 ... 的數(shù)量級(jí)去benchmark,好處就是避免了大量的time.Since 計(jì)算開(kāi)銷(xiāo),因?yàn)閠ime.Since單次在 30ns 左右(Linux環(huán)境下),開(kāi)銷(xiāo)非常大的!

package pprof

import (
    "fmt"
    "sync"
    "sync/atomic"
    "time"
)

func ParallelBenchmark(name string, thread int, duration time.Duration, execute func(count int)) {
    wg := sync.WaitGroup{}
    wg.Add(thread)
    totalCount := uint64(0)
    totalSpend := uint64(0)
    for i := 0; i < thread; i++ {
       go func() {
          defer wg.Done()
          spend, count := Benchmark(duration, execute)
          atomic.AddUint64(&totalSpend, uint64(spend))
          atomic.AddUint64(&totalCount, uint64(count))
       }()
    }
    wg.Wait()
    fmt.Printf("name=%s thread=%d duration=%s total=%d avg=%s\n", name, thread, duration, totalCount, Avg(time.Duration(totalSpend), int(totalCount)))
}

func Avg(spend time.Duration, count int) string {
    avg := float64(spend) / float64(count)
    if avg > 100 {
       return time.Duration(avg).String()
    }
    return fmt.Sprintf("%.4fns", avg)
}

func Benchmark(duration time.Duration, bench func(count int)) (time.Duration, int) {
    const maxTotalCount = 1000000000 // 10E
    count := 1
    totalSpend := time.Duration(0)
    totalCount := 0
    for {
       start := time.Now()
       bench(count)
       spend := time.Since(start)

       totalSpend = totalSpend + spend
       totalCount = totalCount + count

       if totalCount >= maxTotalCount {
          break
       }
       subSpend := duration - totalSpend
       if subSpend <= 0 {
          break
       }
       count = totalCount*10 - totalCount
       if subCount := int(float64(subSpend) / (float64(totalSpend) / float64(totalCount))); count > subCount {
          count = subCount
       }
    }
    return totalSpend, totalCount
}

profile 實(shí)現(xiàn)

package pprof

import (
    "net/http"
    _ "net/http/pprof"
    "os"
    "runtime"
    "runtime/pprof"
)

// InitPProf
// go InitPProf()
func InitPProf() {
    err := http.ListenAndServe(":12345", http.DefaultServeMux)
    if err != nil {
       panic(err)
    }
}

func StartCPUProfile(fileName string) (stop func()) {
    f, err := os.Create(fileName)
    if err != nil {
       panic(err)
    }
    if err := pprof.StartCPUProfile(f); err != nil {
       if err := f.Close(); err != nil {
          panic(err)
       }
       panic(err)
    }
    return func() {
       pprof.StopCPUProfile()
       if err := f.Close(); err != nil {
          panic(err)
       }
    }
}

func StartMemProfile(fileName string) (stop func()) {
    f, err := os.Create(fileName)
    if err != nil {
       panic(err)
    }
    return func() {
       defer func() {
          if err := f.Close(); err != nil {
             panic(err)
          }
       }()
       runtime.GC() // get up-to-date statistics
       if err := pprof.WriteHeapProfile(f); err != nil {
          panic(err)
       }
    }
}

例子

package main

import (
	"github.com/anthony-dong/golang/pkg/pprof"
	"sync"
	"time"
)

func main() {
	// 記錄 cup pprof
	//stop := pprof.StartCPUProfile("cpu.out")
	//defer stop()

	// 并發(fā)測(cè)試 sync map的性能
	mm := sync.Map{}
	pprof.ParallelBenchmark("test1", 64, time.Second, func(count int) {
		for i := 0; i < count; i++ {
			mm.Store(i%10000, 1)
		}
	})
	// name=test1 thread=32 duration=1s total=6708009 avg=4.772μs
	// name=test1 thread=64 duration=1s total=6883456 avg=9.3μs
}

到此這篇關(guān)于Go語(yǔ)言如何實(shí)現(xiàn)Benchmark函數(shù)的文章就介紹到這了,更多相關(guān)Go Benchmark內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang常見(jiàn)錯(cuò)誤之值拷貝和for循環(huán)中的單一變量詳解

    Golang常見(jiàn)錯(cuò)誤之值拷貝和for循環(huán)中的單一變量詳解

    這篇文章主要給大家介紹了關(guān)于Golang常見(jiàn)錯(cuò)誤之值拷貝和for循環(huán)中單一變量的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • docker中部署golang項(xiàng)目的步驟詳解

    docker中部署golang項(xiàng)目的步驟詳解

    這篇文章主要給大家介紹了關(guān)于在docker中部署golang項(xiàng)目的步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 獲取Golang環(huán)境變量的三種方式小結(jié)

    獲取Golang環(huán)境變量的三種方式小結(jié)

    本文介紹了Golang中獲取環(huán)境變量的三種方式,包含使用Viper包、GoDotEnv包和os包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • 在goland中讀取tpl文件的圖文操作

    在goland中讀取tpl文件的圖文操作

    這篇文章主要介紹了在goland中讀取tpl文件的圖文操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Golang使用WebSocket通信的實(shí)現(xiàn)

    Golang使用WebSocket通信的實(shí)現(xiàn)

    這篇文章主要介紹了Golang使用WebSocket通信的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Golang中的Unicode與字符串示例詳解

    Golang中的Unicode與字符串示例詳解

    這篇文章主要給大家介紹了關(guān)于Golang中Unicode與字符串的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • go語(yǔ)言的sql包原理與用法分析

    go語(yǔ)言的sql包原理與用法分析

    這篇文章主要介紹了go語(yǔ)言的sql包原理與用法,較為詳細(xì)的分析了Go語(yǔ)言里sql包的結(jié)構(gòu)、相關(guān)函數(shù)與使用方法,需要的朋友可以參考下
    2016-07-07
  • Go語(yǔ)言設(shè)計(jì)模式之實(shí)現(xiàn)觀察者模式解決代碼臃腫

    Go語(yǔ)言設(shè)計(jì)模式之實(shí)現(xiàn)觀察者模式解決代碼臃腫

    今天學(xué)習(xí)一下用?Go?實(shí)現(xiàn)觀察者模式,觀察者模式主要是用來(lái)實(shí)現(xiàn)事件驅(qū)動(dòng)編程。事件驅(qū)動(dòng)編程的應(yīng)用還是挺廣的,除了我們都知道的能夠用來(lái)解耦:用戶修改密碼后,給用戶發(fā)短信進(jìn)行風(fēng)險(xiǎn)提示之類的典型場(chǎng)景,在微服務(wù)架構(gòu)實(shí)現(xiàn)最終一致性、實(shí)現(xiàn)事件源A?+?ES
    2022-08-08
  • Golang+Vue輕松構(gòu)建Web應(yīng)用的方法步驟

    Golang+Vue輕松構(gòu)建Web應(yīng)用的方法步驟

    本文主要介紹了Golang+Vue輕松構(gòu)建Web應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Golang分布式應(yīng)用之Redis示例詳解

    Golang分布式應(yīng)用之Redis示例詳解

    這篇文章主要為大家介紹了Golang分布式應(yīng)用之Redis示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評(píng)論

柘荣县| 塘沽区| 汪清县| 靖边县| 丹凤县| 安阳县| 通山县| 安阳县| 宜州市| 绥化市| 得荣县| 古田县| 洞口县| 沙湾县| 浙江省| 江口县| 阿鲁科尔沁旗| 富锦市| 富川| 长汀县| 色达县| 科技| 通许县| 大港区| 克什克腾旗| 三都| 顺昌县| 泰来县| 靖江市| 富民县| 锦屏县| 东兰县| 顺昌县| 沙坪坝区| 独山县| 星子县| 平乡县| 米脂县| 新闻| 花垣县| 伊宁县|