天天看點

Go語言 json分析

背景

Go語言自帶的encode/json包提供了對JSON資料格式的編碼和解碼能力。解碼JSON時encode/json包使用UnMarshall或者Decode方法根據開發者提供的存放解碼後資料的變量的類型聲明來解析JSON并把解碼後的資料填充到Go變量裡。是以解析JSON的關鍵其實是如何聲明存放解析後資料的變量的類型。

Marshal函數執行流程

以下為 Go1.12 版本中 json.Marshal 函數的執行流程:

Go語言 json分析

在了解了 json.Marshal 函數的執行流程後,再來比較下在 Go1.10 和 Go1.12 版本中的 json.Marshal 函數在實作上有什麼變化。通過之前的測試,可以發現從 Go1.10 至 Go1.12 版本中的 json.Marshal 函數的記憶體消耗上有了很大的改善。從源碼的變化中可以發現在 Go1.12 版本中的 json.Marshal 函數添加了 encoder(編碼器)的記憶體緩存:

Go語言 json分析

在使用了 sync.Pool 緩存 encoder 後,json.Marshal 函數極大地減少了記憶體配置設定操作。實際上 newEncodeState() 函數在 Go1.10 版本中就已經存在了,隻不過沒有被使用而已。

Unmarshal函數執行流程

以下為 Go1.12 版本中,json.Unmarshal 函數的執行流程:

Go語言 json分析

json.Unmarshal 函數同樣使用 sync.Pool 緩存了 decoder。對于 json 序列化和反序列化而言,其性能瓶頸是疊代、反射 json 結構中每個字段。

參考資料

Go語言中文網微信公衆号