https://github.com/json-iterator/go
仍然使用反射实现,但是比 encoding/json 的版本更快。完整的测试代码: https://github.com/json-iterator/go-benchmark
func Benchmark_array_by_stardard_lib(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
sample := make([]int, 0, 10)
json.Unmarshal([]byte(`[1,2,3,4,5,6,7,8,9]`), &sample)
}
}
500000 2478 ns/op 408 B/op 14 allocs/op
func Benchmark_array_by_jsoniter(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
sample := make([]int, 0, 10)
jsoniter.Unmarshal([]byte(`[1,2,3,4,5,6,7,8,9]`), &sample)
}
}
2000000 740 ns/op 224 B/op 4 allocs/op
和 encoding/json 的区别是,标准库使用的是 reflect.ValueOf ,然后根据 json 的输入情况去找对应的 field 和 element 。而 jsoniter 的实现是反过来的,用 reflect.TypeOf 确定一个 json 的 schema ,然后根据 schema 产生对应的 decoder 。如果 json 输入不符合这个 decoder 则报错。
如果使用更底层的 api ,可以完全避免反射的开销
func Benchmark_array_by_jsoniter_direct(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
sample := make([]uint64, 0, 10)
iter := jsoniter.ParseString(`[1,2,3,4,5,6,7,8,9]`)
for iter.ReadArray() {
sample = append(sample, iter.ReadUint64())
}
}
}
3000000 455 ns/op 112 B/op 2 allocs/op
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.