在Go中优化json.Marshal

问题描述 投票:0回答:1

我有一项服务需要编组大型 JSON(长度约为 50KB)。 一开始,我使用map[string]interface{}并对其进行编码,但它消耗了大量的CPU。然后我尝试将 JSON 映射到结构并对结构进行编码,但它没有解决问题。 我尝试了 ffjson、easyjson 但它们没有改善情况。 你知道我可以做什么优化吗?

enter image description here

json go load marshalling
1个回答
0
投票

过早的优化是万恶之源。

唐纳德·高德纳

显然,您只描述了解码,当然解码将占据解码过程的重要部分。

因此出现了 JSON 解组是否客观有效的问题。

我运行了一些基准测试

package gounmarshalperformance78772815

import (
    "encoding/json"
    "os"
    "testing"

    "github.com/stretchr/testify/require"
)

type unknownJson map[string]interface{}

func benchmark(path string, arraysize int, b *testing.B) {
    d, err := os.ReadFile(path)
    require.NoError(b, err)
    for i := 0; i < b.N; i++ {
        foo := make([]unknownJson, arraysize)
        err := json.Unmarshal(d, &foo)
        require.NoError(b, err)
    }
}

func Benchmark64k(b *testing.B) {
    // Array sizes were determined by running the following command:
    // $ jq length testdata/78772815-{64k,128k,256k}.json
    benchmark("testdata/78772815-64k.json", 197, b)
}

func Benchmark128k(b *testing.B) {
    benchmark("testdata/78772815-128k.json", 788, b)
}

func Benchmark256k(b *testing.B) {
    benchmark("testdata/78772815-256k.json", 792, b)
}

结果如下:

$ go test -bench=. -cpu=1,2,4,6,8,10 
goos: darwin
goarch: arm64
pkg: github.com/mwmahlberg/go-unmarshalperformance-78772815
Benchmark64k                2821            423092 ns/op
Benchmark64k-2              2966            389132 ns/op
Benchmark64k-4              2904            394141 ns/op
Benchmark64k-6              2972            398771 ns/op
Benchmark64k-8              2931            396255 ns/op
Benchmark64k-10             2901            392617 ns/op
Benchmark128k                660           1823380 ns/op
Benchmark128k-2              704           1691047 ns/op
Benchmark128k-4              697           1731524 ns/op
Benchmark128k-6              691           1832979 ns/op
Benchmark128k-8              705           1705955 ns/op
Benchmark128k-10             698           1714762 ns/op
Benchmark256k                658           1842479 ns/op
Benchmark256k-2              690           1705684 ns/op
Benchmark256k-4              687           1747386 ns/op
Benchmark256k-6              680           1738418 ns/op
Benchmark256k-8              696           1763082 ns/op
Benchmark256k-10             687           1760691 ns/op
PASS
ok      github.com/mwmahlberg/go-unmarshalperformance-78772815  25.038s

那么,这告诉我们什么?它告诉我们,大小为 64k 的测试数据 JSON 每秒至少被解组 2821 次

如果这还不够性能,您应该考虑水平缩放。

© www.soinside.com 2019 - 2024. All rights reserved.