avatar🌌
TangentTangent Blog

技术博客 | Go & Kubernetes & Linux

技术博客 | Go & Kubernetes & Linux

Go JSON Library Performance Comparison: Std JSON V1/V2 vs Sonic

All benchmarks run in Go 1.25.1 environment, with data sizes ranging from 1MB to 100MB.

1. Native Standard Library: Std JSON (V1) ​

Native Std JSON refers to the performance of the encoding/json package under default settings. It is renowned for its stability and compatibility, but it has obvious performance bottlenecks when handling large amounts of data, especially during deserialization (Unmarshal).

Example Code: Deserialization (Unmarshal) ​

We use the standard library’s json.Unmarshal to operate on preloaded JSON byte arrays and report memory allocation counts (b.ReportAllocs()).

go
func BenchmarkStdJSONUnmarshal1MB(b *testing.B) {
    b.ReportAllocs()
    for b.Loop() {
        var result []TestData
        err := json.Unmarshal(jsonData1MB, &result) // Using encoding/json
        if err != nil { b.Fatal(err) }
    }
}

Performance Analysis (Based on 100MB Data) ​

Operation TypeAverage Throughput (MB/s)Average Allocations (allocs/op)Source
Marshal (Serialization)Approx. 843 – 878 MB/s2 – 7
Unmarshal (Deserialization)Approx. 157 – 172 MB/sApprox. 699,590 times

Key Insights:

  • Serialization Performance Acceptable: V1 version has relatively high serialization performance, averaging over 800 MB/s.
  • Deserialization Bottleneck: Std JSON V1 has very low throughput during deserialization, only about 20% of serialization performance.
  • High GC Pressure: The most significant issue is memory allocation. When deserializing 100MB of data, it generates nearly 700,000 allocations, putting enormous pressure on the Go runtime’s garbage collection (GC) system, which is the main cause of its poor performance.

Launch Instructions (Std JSON V1) ​

Run all benchmarks containing StdJSON in the name:

shell
go test -bench=StdJSON -count=10 -benchmem ...

task benchmark-std

2. JSON V2 (Go 1.25 Experimental) ​

JSON V2 is an experimental implementation introduced in Go 1.25 to optimize standard library performance. Its calling interface is identical to V1, but it is enabled by setting the GOEXPERIMENT jsonv2 flag.

Example Code: Deserialization (Unmarshal) ​

Although the underlying implementation differs, the user code remains unchanged, still using the encoding/json package:

go
// Code same as V1, but GOEXPERIMENT flag activates V2 logic
err := json.Unmarshal(jsonData1MB, &result)

Performance Analysis (Based on 100MB Data) ​

Operation TypeAverage Throughput (MB/s)Average Allocations (allocs/op)Source
Marshal (Serialization)Approx. 810 – 853 MB/s3 – 9
Unmarshal (Deserialization)Approx. 325 – 348 MB/sApprox. 653,504 times

Key Insights:

  • Serialization Improvement Not Obvious: V2’s throughput in serialization (Marshal) is roughly the same as V1.
  • Significant Deserialization Improvement: V2 excels in deserialization (Unmarshal), with throughput doubled compared to V1 (157 MB/s to approx. 347 MB/s).
  • Memory Allocation Issues Persist: Despite the speed increase, V2 still has high memory allocation counts (approx. 650,000 times), meaning it still causes high GC pressure.

Launch Instructions (JSON V2) ​

Must set the GOEXPERIMENT jsonv2 environment variable to enable V2 implementation:

shell
set -x GOEXPERIMENT jsonv2
go test -bench=StdJSO -count=10 -benchmem ...

task benchmark-jsonv2

3. Third-Party Library: Sonic ​

Sonic (github.com/bytedance/sonic) is a highly optimized JSON library, commonly used in scenarios with extremely high performance requirements. The tests use its fastest configuration (sonic.ConfigFastest).

Example Code: Deserialization (Unmarshal - Fastest Configuration) ​

Sonic provides dedicated APIs, which can be used directly with sonic.Unmarshal or a pre-configured sonicFastest instance:

go
// Pre-configured fastest instance
var sonicFastest = sonic.ConfigFastest

func BenchmarkSonicFastestUnmarshal1MB(b *testing.B) {
    b.ReportAllocs()
    for b.Loop() {
        var result []TestData
        // Use ConfigFastest instance for deserialization
        err := sonicFastest.Unmarshal(jsonData1MB, &result) 
        if err != nil { b.Fatal(err) }
    }
}

Performance Analysis (Based on 100MB Data) ​

Operation TypeAverage Throughput (MB/s)Average Allocations (allocs/op)Source
Marshal (Serialization)Approx. 952 – 987 MB/s33 – 34 times
Unmarshal (Deserialization)Approx. 1090 – 1107 MB/sApprox. 50,250 times

Key Insights:

  • Serialization Leading: Sonic’s serialization performance surpasses V1 and V2, reaching nearly 1000 MB/s.
  • Massive Deserialization Advantage: Sonic shows overwhelming superiority in deserialization, with throughput exceeding 1 GB/s, which is 6 times V1 and 3 times V2.
  • Revolutionary Memory Efficiency Improvement: When deserializing 100MB of data, Sonic has only 50,250 allocations, reducing the nearly 700,000 allocations of V1/V2 by more than an order of magnitude, greatly reducing GC pressure.

Launch Instructions (Sonic) ​

Run all benchmarks containing Sonic in the name:

shell
go test -bench=Sonic -count=10 -benchmem ...

task benchmark-sonic

4. Performance Summary and Selection Analysis ​

The table below compares the key performance indicators of the three JSON processing mechanisms when handling large JSON data (100MB):

ImplementationUnmarshal Throughput (MB/s)Marshal Throughput (MB/s)Unmarshal Allocations (allocs/op)GC PressureDependencies
Std JSON (V1)157 – 172843 – 878High (≈ 700k)Extremely HighNone (Standard Library)
JSON V2 (Go 1.25)325 – 348810 – 853High (≈ 650k)HighNone (Standard Library, requires experimental flag)
Sonic (Fastest)1090 – 1107952 – 987Low (≈ 50k)LowExternal Library

Selection Strategy Analysis ​

When choosing a JSON library for a Go project, consider the project’s performance requirements, dependency constraints, and Go version:

  1. Preferred Sonic (Extreme Performance Requirements)

    • Applicable Scenarios: High-concurrency services with extremely high throughput requirements (e.g., API Gateway, data processing pipelines), and latency-sensitive scenarios with large data volumes.
    • Advantages: Highest performance in both serialization and deserialization. Most importantly, it greatly optimizes memory allocations (deserialization allocations reduced by an order of magnitude compared to native libraries), significantly reducing GC burden.
    • Cost: Introduces external dependencies.
  2. Secondary JSON V2 (Standard Library Performance Boost)

    • Applicable Scenarios: Running on Go 1.25 and higher versions, needing to maintain standard library compatibility while achieving significant performance improvements without external dependencies.
    • Advantages: Deserialization speed is twice that of V1, but still part of the standard library, no need to manage additional dependencies.
    • Cost: Must enable experimental flag (GOEXPERIMENT jsonv2), and memory allocation counts during deserialization remain high (high GC pressure).
  3. Basic Std JSON V1 (Compatibility and Stability)

    • Applicable Scenarios: Basic services where performance requirements are not high, and maximum cross-version compatibility and code stability are needed.
    • Advantages: Default standard library behavior, no configuration required, most stable and universal.
    • Cost: Worst deserialization performance when handling large JSON payloads, with highest GC latency due to memory allocations.
如何正确处理gRPC错误处理
Go JSON 库性能对比:Std JSON V1/V2 vs Sonic
由 Valaxy v1.2.2 驱动|主题-Yunv1.2.2