首页 > 其他分享 >golang json 性能分析

golang json 性能分析

时间:2024-06-01 23:10:42浏览次数:19  
标签:struct iterator easyjson 性能 golang json 序列化

  Json 作为一种重要的数据格式,具有良好的可读性以及自描述性,广泛地应用在各种数据传输场景中。Go 语言里面原生支持了这种数据格式的序列化以及反序列化,内部使用反射机制实现,性能有点差,在高度依赖 json 解析的应用里,往往会成为性能瓶颈,从下面的火焰图中可以发现在业务逻辑处理中,有一半多的性能消耗都是在 JSON 解析过程中,有很多第三方库帮忙解决了这个问题,接下来分析一下常用的几个库。

 

 

encoding/json

  • encoding/json是官方提供的标准json, 实现RFC 7159中定义的JSON编码和解码。
  • 使用的时候需要预定义struct,原理是通过reflectioninterface来完成工作, 性能低。

常用接口:

  • func Marshal(v interface{}) ([]byte, error) 生成JSON
  • func Unmarshal(data []byte, v interface{}) error 解析JSON到struct
import "encoding/json"
json.Marshal(&data)

json-iterator

使用modern-go/reflect2来优化反射性能。然后就是通过大幅度减少反射操作,来提高速度。

  • 完全兼容json标准库,也就是API用法完全一样,原有代码不需要改动。
  • 提供了一个兼容模式(需要手动开启),可以自动转换字符串/数字弱类型问题,可以转换[]与{}弱类型问题(PHP中的array问题)。

Github: https://github.com/json-iterator/go

package main

import (
    "fmt"
    jsoniter "github.com/json-iterator/go"
    "github.com/json-iterator/go/extra"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

func init() {
    // RegisterFuzzyDecoders decode input from PHP with tolerance.
    //  It will handle string/number auto conversation, and treat empty [] as empty struct.
    extra.RegisterFuzzyDecoders() // 手动开启兼容模式
}

type StdStruct struct {
    Age int `json:"age"`
}

func main() {
    s := "{\"age\": \"10\"}"

    d := &StdStruct{}

    if err := json.Unmarshal([]byte(s), d); err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(d.Age)  // 开启兼容模式后,可以解析出字符串下的10
    }
}

注意:只需要在main文件里通过init开启1次PHP兼容模式即可,后续引入的模块不需要重复开启。

以下是对一个对象序列化1000次,所用的耗时对比

json-iterator的on

easyjson 的思想是增加一个预编译的过程,预先生成对应结构的序列化反序列化代码,除此之外,easyjson 还放弃了一些原生库里面支持的一些不必要的特性,比如:key 类型声明,key 大小写不敏感等等,以达到更高的性能

生成代码执行 easyjson -all <file.go> 即可,如果不指定 -all 参数,只会对带有 //easyjson:json 的结构生成代码

//easyjson:json
type A struct {
    Bar string
}

性能测试

 从上面的结果可以看出来:

  • easyjson 无论是序列化还是反序列化都是最优的,序列化提升了1倍,反序列化提升了3倍
  • jsoniter 性能也很好,接近于easyjson,关键是没有预编译过程,100%兼容原生库
  • ffjson 的序列化提升并不明显,反序列化提升了1倍
  • codecjson 和原生库相比,差不太多,甚至更差
  • jsonparser 不太适合这样的场景,性能提升并不明显,而且没有反序列化

所以综合考虑,建议使用 jsoniter,如果追求极致的性能,考虑 easyjson。

标签:struct,iterator,easyjson,性能,golang,json,序列化
From: https://www.cnblogs.com/beatle-go/p/18221843

相关文章

  • CSAPP 第五章 优化程序性能
    5-1&2优化程序性能保守性编译器优化是保守的,只要有矛盾就不会激进的优化。CPECPE表示每个元素执行所需要的周期数。如368+6*k,6就是CPE。一个优化的例子这个代码每一次迭代要读两次内存,写入一次。这个只用读一次。以上优化会有一定的效果,读写内存是占用时间的。5-3......
  • 噪声嵌入提升语言模型微调性能
     在自然语言处理(NLP)的快速发展中,大模型(LLMs)的微调技术一直是研究的热点。最近,一篇名为《NEFTUNE:NOISYEMBEDDINGSIMPROVEINSTRUCTIONFINETUNING》的论文提出了一种新颖的方法,通过在训练过程中向嵌入向量添加噪声来提升模型的微调性能。这一发现为LLMs的进一步优化提供了......
  • Java多线程编程:提高程序性能与响应性
            多线程编程是利用计算机的多核心优势来提高程序的性能和响应性的重要手段之一。在Java中,通过多线程可以实现同时执行多个任务,充分利用CPU资源,加速程序的运行。本文将深入探讨Java多线程编程的基本概念、常用类库、并发问题以及最佳实践。####1.多线程基础概......
  • 太阳能辐射整车综合性能环境试验舱
    产品别名步入式恒温恒湿试验箱、步入式温湿度试验箱、温度试验室、模拟环境试验室、大型恒温恒湿箱、步入式高低温湿热交变试验箱、大型高低温箱、步入式老化箱、恒温恒湿试验房、步入式高低温试验箱.整车综合性能环境试验舱:整车综合性能环境试验舱:主要用于整车高低温存放......
  • golang GMP机制
    GMP是Golang底层实现的一种调度协程的方案,目的是提高并发处理且降低切换成本。GMP分别是底层实现中的三个数据结构。g代表goroutine,指被调度的协程对象。m代表线程,它是操作系统级别的线程,用来执行程序中的协程。p代表processer,是CPU的抽象。默认情况下,go程序会为每个CPU创......
  • 在Linux中,如何进行硬件性能监控?
    在Linux中,硬件性能监控是确保系统高效运行和及时发现硬件问题的重要环节。以下是一些常用的命令和工具,用于监控CPU、内存、磁盘、网络接口以及特定硬件组件(如温度、电压等)的状态。1.CPU监控top和htop:实时显示各进程的CPU使用情况,有助于识别CPU使用率高的进程。mpstat(多处理......
  • form.is_valid()一直为False,且form.errors.as_json()为空
    form.is_valid()一直为False且form.errors.as_json()为空。这种情况通常是由于提交的数据未能正确绑定到表单字段。为了排查这个问题,需要逐步检查以下几个方面:检查HTML表单:确保HTML表单的输入字段名称与LoginForm中的字段名称匹配。确保表单的method属性设置为POST,并且包含{......
  • 10.Golang中的数组
    1、Array(数组)的介绍数组是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),这种类型可以是任意的原始类型,比如int、string等,也可以是用户自定义的类型。一个数组包含的元素个数被称为数组的长度。在Golang中数组是一个长度固定的数据类型,数组的长......
  • 11.Golang中的切片
    1、为什么要使用切片因为数组的长度是固定的并且数组长度属于类型的一部分,所以数组有很多的局限性。例如:packagemainfuncarraySum(x[4]int)int{sum:=0for_,v:=rangex{ sum=sum+v}returnsum}funcmain(){a:=[4]int{1,......
  • 1v1视频软件源码,通过jsonp跨域的代码分析
    1v1视频软件源码,通过jsonp跨域的代码分析通常为了减轻1v1视频软件源码web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实......