切片转JSON优化策略
- 使用
json.Marshal
优化:json.Marshal
在处理大切片时,尽量一次性处理完所有数据。为减少内存分配次数,提前计算切片长度并预留空间。
package main
import (
"encoding/json"
"fmt"
)
func main() {
// 假设这是一个非常大的切片
largeSlice := make([]int, 1000000)
for i := range largeSlice {
largeSlice[i] = i
}
// 预分配足够的空间
buf := make([]byte, 0, len(largeSlice)*10)
var err error
buf, err = json.Marshal(largeSlice)
if err != nil {
fmt.Println("Marshal error:", err)
return
}
fmt.Println(string(buf))
}
- 流式处理(如果适用):如果切片数据是源源不断生成的,可考虑使用
json.Encoder
进行流式编码。
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
largeSlice := make([]int, 1000000)
for i := range largeSlice {
largeSlice[i] = i
}
file, err := os.Create("output.json")
if err != nil {
fmt.Println("Create file error:", err)
return
}
defer file.Close()
encoder := json.NewEncoder(file)
err = encoder.Encode(largeSlice)
if err != nil {
fmt.Println("Encode error:", err)
}
}
JSON转切片优化策略
- 使用
json.Unmarshal
优化:在将JSON数据转换为切片时,提前知道数据结构可预分配切片空间。
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsonData := `[1,2,3,4,5]`
var largeSlice []int
// 预分配一定空间
largeSlice = make([]int, 0, 1000)
err := json.Unmarshal([]byte(jsonData), &largeSlice)
if err != nil {
fmt.Println("Unmarshal error:", err)
return
}
fmt.Println(largeSlice)
}
- 流式处理(
json.Decoder
):对于非常大的JSON数据,使用json.Decoder
逐块读取数据并解析,避免一次性将整个JSON数据读入内存。
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
file, err := os.Open("large.json")
if err != nil {
fmt.Println("Open file error:", err)
return
}
defer file.Close()
decoder := json.NewDecoder(file)
var largeSlice []int
for decoder.More() {
var num int
err := decoder.Decode(&num)
if err != nil {
fmt.Println("Decode error:", err)
return
}
largeSlice = append(largeSlice, num)
}
fmt.Println(largeSlice)
}
避免内存溢出的通用策略
- 及时释放内存:不再使用的变量,确保其不再被引用,以便垃圾回收器能及时回收内存。
- 分批处理:如果数据量太大无法一次性处理,可将数据分成多个批次处理,处理完一批释放一批内存。
- 监控内存使用:在程序运行过程中,使用Go语言的内置工具(如
runtime
包)监控内存使用情况,及时发现潜在的内存问题。