亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在“預熱”之后解組 JSON 的速度要快得多?

為什么在“預熱”之后解組 JSON 的速度要快得多?

Go
慕的地6264312 2023-03-21 17:33:18
我注意到,當我在 Go HTTP 服務器的上下文中計時 JSON 解組時,即使對于小對象也需要 30,000+ 納秒。這對我來說似乎很大,所以我運行了一些獨立的基準測試,結果令人驚訝地顯示每次解組的平均時間約為 500 納米。為了更深入地研究這個問題,我編寫了一個程序,它只對同一個小對象執行一系列解組,這表明第一個解組很慢,而后續的要快得多:package mainimport (    "time"    "fmt"    "encoding/json")var b []bytetype Dog struct {    Age int `json:"Age"`}func unmarshalDog() {    dogCopy := Dog{}    start := time.Now().UnixNano()    json.Unmarshal(b, &dogCopy)    end := time.Now().UnixNano()    fmt.Printf("Time to marshal/unmarshal: %d\n", end-start)}func main() {    // Marshal an object into a byte array which we will repeatedly unmarshal from    d := Dog {        Age: 5,    }    var err error    b, err = json.Marshal(d)    if err != nil {        panic(err)    }    for i := 0; i < 20; i++ {        unmarshalDog()    }    // Allow the goroutines to finish before terminating execution.    time.Sleep(3 * time.Second)}輸出:$ go run testJSONPerformance.goTime to marshal/unmarshal: 34127Time to marshal/unmarshal: 1465Time to marshal/unmarshal: 979Time to marshal/unmarshal: 892Time to marshal/unmarshal: 849Time to marshal/unmarshal: 814Time to marshal/unmarshal: 822Time to marshal/unmarshal: 822Time to marshal/unmarshal: 815Time to marshal/unmarshal: 829Time to marshal/unmarshal: 822Time to marshal/unmarshal: 819unmarshalDog()更有趣的是,當我運行同一個程序但在一個單獨的 goroutine 中運行每次調用viago unmarshalDog()時,預熱現象消失并且平均解組時間長得多:Time to marshal/unmarshal: 36540Time to marshal/unmarshal: 4652Time to marshal/unmarshal: 56959Time to marshal/unmarshal: 3887Time to marshal/unmarshal: 57068Time to marshal/unmarshal: 3519Time to marshal/unmarshal: 37160我還嘗試了一個版本,而不是解組相同的字節數組,我每次都編組和解組一個不同的對象(以防某種運行時緩存正在進行)。在這種情況下,結果是一樣的。我非常想知道這種明顯的“熱身”是怎么回事。在 HTTP 服務器的上下文中,每個請求都會得到一個不同的 goroutine,因此每個解組平均來說都非常慢。這似乎不是最理想的,因為顯然 Go 有可能在特定上下文中用 1/50 的時間進行解組。所有直覺贊賞!
查看完整描述

1 回答

?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

JSON 解組器緩存有關任何類型的第一次解組的信息。該類型的后續解組使用此緩存信息。

緩存在 goroutine 之間共享,但是沒有代碼來確保只有一個 goroutine 嘗試創建第一個緩存值。一旦一個 goroutine 將一個值存儲到緩存中,所有新來者都將使用該緩存值。

緩存的代碼在這里。


查看完整回答
反對 回復 2023-03-21
  • 1 回答
  • 0 關注
  • 106 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號