[第三方库推荐] simdjson-go Golang 高性能 JSON 解析器,十倍于 encoding/JSON
simdjson-go
简介
这是 Golang 版本的 simdjson,一个高性能的 JSON 解析器。在架构上使用 SIMD 指令来获取每秒处理千兆 JSON 数据的性能。
大部分情况下,simdjson-go
差不多能有 40% 到 60% 于 simdjson 的速度。此速度也会比 Golang 官方的 encoding/json
快差不多十倍。
特性
simdjson-go
是一个验证解析器,这意味着它会验证和检查数值、布尔值等。因此,这些值在解析后可用作适当的 int
和 float64
表示。
此外simdjson-go
具有以下功能:
- 没有4 GB对象限制
- 支持 ndjson (换行分隔的json)
- 适当的内存管理
- 纯 Go (不需要cgo)
与 simdjson 的性能对比
基于相同的 JSON 测试文件集,下图显示了 simdjson
与simdjson-go
之间的比较:
这些数字是在配备 3.1 GHz Intel Core i7 的 MacBook Pro 上测量的。此外,为了使它公平地进行比较,将常数 GOLANG_NUMBER_PARSING
设为 false
(默认为 true
),以便使用相同的数字解析函数(以某些精度为代价更快;参见下文)。
encoding/json
和 json-iterator/go
性能对比
以下它是基于同一组JSON测试文件与Golang标准包 encoding/json
的性能比较。
$ benchcmp encoding_json.txt simdjson-go.txt
benchmark old MB/s new MB/s speedup
BenchmarkApache_builds-8 106.77 948.75 8.89x
BenchmarkCanada-8 54.39 519.85 9.56x
BenchmarkCitm_catalog-8 100.44 1565.28 15.58x
BenchmarkGithub_events-8 159.49 848.88 5.32x
BenchmarkGsoc_2018-8 152.93 2515.59 16.45x
BenchmarkInstruments-8 82.82 811.61 9.80x
BenchmarkMarine_ik-8 48.12 422.43 8.78x
BenchmarkMesh-8 49.38 371.39 7.52x
BenchmarkMesh_pretty-8 73.10 784.89 10.74x
BenchmarkNumbers-8 160.69 434.85 2.71x
BenchmarkRandom-8 66.56 615.12 9.24x
BenchmarkTwitter-8 79.05 1193.47 15.10x
BenchmarkTwitterescaped-8 83.96 536.19 6.39x
BenchmarkUpdate_center-8 73.92 860.52 11.64x
那么 simdjson-go
使用较少的额外内存和分配。
这是它和另一个包 json-iterator/go
的基准测试比较:
$ benchcmp json-iterator.txt simdjson-go.txt
benchmark old MB/s new MB/s speedup
BenchmarkApache_builds-8 154.65 948.75 6.13x
BenchmarkCanada-8 40.34 519.85 12.89x
BenchmarkCitm_catalog-8 183.69 1565.28 8.52x
BenchmarkGithub_events-8 170.77 848.88 4.97x
BenchmarkGsoc_2018-8 225.13 2515.59 11.17x
BenchmarkInstruments-8 120.39 811.61 6.74x
BenchmarkMarine_ik-8 61.71 422.43 6.85x
BenchmarkMesh-8 50.66 371.39 7.33x
BenchmarkMesh_pretty-8 90.36 784.89 8.69x
BenchmarkNumbers-8 52.61 434.85 8.27x
BenchmarkRandom-8 85.87 615.12 7.16x
BenchmarkTwitter-8 139.57 1193.47 8.55x
BenchmarkTwitterescaped-8 102.28 536.19 5.24x
BenchmarkUpdate_center-8 101.41 860.52 8.49x
使用方法
执行一下命令安装 simdjson-go
$ go get github.com/minio/simdjson-go
为了解析JSON字节流, 你也可以调用 simdjson.Parse()
或者 simdjson.ParseND()
解析换行符分隔的 JSON 文件。这两个函数都返回一个 ParsedJson
结构,可以通过该结构调用 Iter()
来浏览 JSON 对象。
使用 Iter
类型, 你可以调用 Advance()
去迭代遍历类型(原文是tape,感觉有点不对。),如下所示:
for {
typ := iter.Advance()
switch typ {
case simdjson.TypeRoot:
if typ, tmp, err = iter.Root(tmp); err != nil {
return
}
if typ == simdjson.TypeObject {
if obj, err = tmp.Object(obj); err != nil {
return
}
e := obj.FindKey(key, &elem)
if e != nil && elem.Type == simdjson.TypeString {
v, _ := elem.Iter.StringBytes()
fmt.Println(string(v))
}
}
default:
return
}
}
在示例子目录中可以找到更多示例,并且可以在 godoc 上找到更多文档。
要求
simdjson-go
具有以下要求:
- 需要同时具有AVX2和CLMUL的CPU(从2013年起Haswell应该用于Intel,对于AMD而言,一个 Ryzen/EPIC CPU(2017年第一季度)就足够了)。可以使用提供的
SupportedCPU()
函数进行检查。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: