热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golangjson编码map与struct结构的对比

本文对比试验采用官方包做jsonmap和struct编码。原文连接:http:blog.lpflpf.cnpassage…数据构造map数据类型为map[string]string

本文对比试验采用官方包做json map 和struct 编码。

原文连接:http://blog.lpflpf.cn/passage…

数据构造

map 数据类型为map[string]string , key 长度为10, val 长度为100
struct 定义如下:

type Object struct {
Xvlbzgbaic string `json:"xvlbzgbaic"`
Krbemfdzdc string `json:"krbemfdzdc"`
Rzlntxyeuc string `json:"rzlntxyeuc"`
Ctzkjkziva string `json:"ctzkjkziva"`
Orsufumaps string `json:"orsufumaps"`
Hyevwbtcml string `json:"hyevwbtcml"`
Baatlyhdao string `json:"baatlyhdao"`
Fkfohsvvxs string `json:"fkfohsvvxs"`
Pqwarpxptp string `json:"pqwarpxptp"`
Orvaukawww string `json:"orvaukawww"`
}

对比程序如下:

obj := Object{}
json.Unmarshal([]byte(str), &obj)
start := time.Now()
for i := 0; i <1000000; i++ {
json.Marshal(obj)
}
fmt.Println(time.Since(start))
maps := map[string]string{}
json.Unmarshal([]byte(str), &maps)
start = time.Now()
for i := 0; i <1000000; i++ {
json.Marshal(maps)
}
//
fmt.Println(time.Since(start))

其中,str 为生成好的固定json数据, 我们对相同的数据做json 编码, 运行结果可以看出,时间差距大约为1倍,若将map的key 个数调整为100个

运行次数均为1000,000 次

type\ keys 个数101001000
struct3.84s33.72s5m42.34s
map[string]string7.59s1m20.03s17m21.47s
no sorting map[string]string6.40s57.61s10m4.39s

从上述对比中,得出如下结论:

在大量使用json 编码时(尤其是map结构较大时),请注意尽量直接用struct,而不是用map做编码。

原因探究

  • map 编码问题

    • struct 多次压缩时,encoding 中会缓存 name 信息, 以及对应val的类型,直接调用相应的encoder 即可;相反,map 则每次需要对key 做反射,根据类型判断获取key的值,val值也需要反射获取相应的encoder,时间浪费较多。
    • map 在做json 的解析的结果,会做排序操作。若修改源码,将排序操作屏蔽,key 越多,需要的时间越多。
  • map 编码

// go/src/encoding/json/encode.go
func (me *mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
if v.IsNil() {
e.WriteString("null")
return
}
e.WriteByte('{')
// Extract and sort the keys.
keys := v.MapKeys()
sv := make([]reflectWithString, len(keys))
for i, v := range keys {
sv[i].v = v
if err := sv[i].resolve(); err != nil {
e.error(&MarshalerError{v.Type(), err})
}
}
// 在输出前会做key 的排序,最后按照key 排序的结果做输出
sort.Slice(sv, func(i, j int) bool { return sv[i].s for i, kv := range sv {
if i > 0 {
e.WriteByte(',')
}
e.string(kv.s, opts.escapeHTML)
e.WriteByte(':')
me.elemEnc(e, v.MapIndex(kv.v), opts)
}
e.WriteByte('}')
}

  • struct 编码

// go/src/encoding/json/encode.go
type structEncoder struct {
fields []field
fieldEncs []encoderFunc
}
func newStructEncoder(t reflect.Type) encoderFunc {
fields := cachedTypeFields(t) // 从cache 中获取fields
se := &structEncoder{
fields: fields,
fieldEncs: make([]encoderFunc, len(fields)),
}
for i, f := range fields {
se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))
}
return se.encode
}
func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
e.WriteByte('{')
first := true
for i, f := range se.fields { // fields 被缓存在structEncoder 结构体中
fv := fieldByIndex(v, f.index)
if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
continue
}
if first {
first = false
} else {
e.WriteByte(',')
}
e.string(f.name, opts.escapeHTML)
e.WriteByte(':')
opts.quoted = f.quoted
se.fieldEncs[i](e, fv, opts)
}
e.WriteByte('}')
}

json-iterator/go

根据上述内容,对比github.com/json-iterator/go 与 encoding/json 的对比试验,也可以看出,iterator 对 map 的性能提升不是很明显(由于都需要做反射),后续将做试验验证。

Env

  • 机器环境: 1C1G
  • golang 版本: go1.10.3 linux/amd64

推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有