避免不必要的内存分配
- 提前预分配切片和映射:在序列化或反序列化之前,根据数据量提前分配足够的内存空间,避免在操作过程中动态分配内存。
package main
import (
"encoding/json"
"fmt"
)
func main() {
// 预分配切片
var data []map[string]interface{}
data = make([]map[string]interface{}, 100)
for i := 0; i < 100; i++ {
data[i] = make(map[string]interface{})
data[i]["key"] = i
}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Marshal error:", err)
return
}
fmt.Println(string(jsonData))
}
- 减少中间变量:直接在目标对象上进行操作,而不是创建多个中间对象。
利用sync.Pool进行对象复用
- 定义对象池:
sync.Pool
可以用来缓存临时对象,减少内存分配。
package main
import (
"encoding/json"
"fmt"
"sync"
)
var bufPool = sync.Pool{
New: func() interface{} {
return &json.EncoderBuffer{}
},
}
func main() {
data := map[string]interface{}{"key": "value"}
buf := bufPool.Get().(*json.EncoderBuffer)
defer bufPool.Put(buf)
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Marshal error:", err)
return
}
fmt.Println(string(jsonData))
}
- 复用编码器和解码器:对于编码器
json.Encoder
和解码器 json.Decoder
也可以使用 sync.Pool
进行复用。
选择合适的JSON库
- 标准库
encoding/json
:Go 标准库中的 encoding/json
性能已经比较不错,但在高并发场景下仍有提升空间。
json-iterator/go
:这是一个高性能的JSON库,兼容标准库接口,性能比标准库更好。
package main
import (
jsoniter "github.com/json-iterator/go"
"fmt"
)
func main() {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
data := map[string]interface{}{"key": "value"}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println("Marshal error:", err)
return
}
fmt.Println(string(jsonData))
}
fastjson
:该库专为高性能JSON解析设计,在反序列化大JSON数据时性能优势明显。但它的接口与标准库不完全兼容,使用时需要注意。