SpringBoot中这样用ObjectMapper

  • 每次new一个
  • 单例化
  • 个性化配置
  • 小结

你要说他有问题吧,确实能正常执行;可你要说没问题吧,在追求性能的同学眼里,这属实算是十恶不赦的代码了。

首先,让我们用JMH对这段代码做一个基准测试,让大家对其性能有个大概的了解。

基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。而JMH是一个用来构建,运行,分析Java或其他运行在JVM之上的语言的 纳秒/微秒/毫秒/宏观 级别基准测试的工具。

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 3, time = 1)
public class JsonJMHTest {

    String json = "{\"id\":122345667,\"email\":\"jianzh5@163.com\",\"price\":12.25}";
    UserEntity userEntity = new UserEntity(13345L,"jianzh5@163.com", BigDecimal.valueOf(12.25));
    /**
     * 测试String to Object
     */
    @Benchmark
    public UserEntity objectMapper2ObjTest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(json, UserEntity.class);
    }

    /**
     * 测试Object to String
     */
    @Benchmark
    public String objectMapper2StringTest() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(userEntity);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JsonJMHTest.class.getSimpleName())
                .build();
        new Runner(opt).run();
    }
}

测试环境

# JMH version: 1.36
# VM version: JDK 17.0.3, OpenJDK 64-Bit Server VM, 17.0.3+7-LTS
# Mac AppleM1/16GB

测试结果

通过测试结果可以看出,每次new一个ObjectMapper,在实现字符串转对象时每秒可以完成23万多次,而实现对象转Json字符串每秒仅可完成2.7万次。

那该如何优化,提升性能呢?

单例化

老鸟们都知道,在创建工具类时要将工具类设置成单例的,这样不仅可以保证线程安全,也可以保证在系统全局只能创建一个对象,避免频繁创建对象的成本。

所以,我们可以在项目中构建一个ObjectMapper的单例类。


@Getter
public enum ObjectMapperInstance {

    INSTANCE;

    private final ObjectMapper objectMapper = new ObjectMapper();

    ObjectMapperInstance() {

    }
}

再次使用JMH对其测试:

@Benchmark
public UserEntity singleten2ObjTest() throws JsonProcessingException {
        ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
        return objectMapper.readValue(json, UserEntity.class);
        }

@Benchmark
public String singleten2StringTest() throws JsonProcessingException {
        ObjectMapper objectMapper = ObjectMapperInstance.INSTANCE.getObjectMapper();
        return objectMapper.writeValueAsString(userEntity);
        }

测试结果如下:

可以看到,使用单例模式,String转对象的方法每秒可以执行420多万次,比new ObjectMapper的方式快了18倍;而对象转String的方法每秒可以执行830万次,性能提升了300倍(看到结果的一瞬间我傻眼了,一度怀疑是写错代码了)!!!!

个性化配置

当然,在项目中使用ObjectMapper时,有时候我们还需要做一些个性化配置,比如将Long和BigDemical类型的属性都通过字符串格式进行转换,防止前端使用时丢失数值精度。

这些类型转换的格式映射都可以在单例类中配置,代码如下:

@Getter
public enum ObjectMapperInstance {

    INSTANCE;

    private final ObjectMapper objectMapper;

    ObjectMapperInstance() {
        objectMapper = new ObjectMapper();
        // 注册自定义模块
        initialize();
    }

    private void initialize() {
        CustomJsonModule customJsonModule = new CustomJsonModule();
        objectMapper.registerModule(customJsonModule);
    }
}

在initialize()方法中给ObjectMapper注册自定义序列化转换器。

第一行是使用注册自定义序列换转换器后的效果,给id和price字段都加上了引号。

再来一次JMH测试:

可以看到,给ObjectMapper额外注册转换类型以后性能会受到一定的影响,但对业务影响不大。(啥业务能这么高的请求~)

小结

通过上面的测试,结论已经很清晰了。使用单例模式进行字符串转对象时性能可以提升18倍,而对象转String性能快了惊人的290万倍,所以在Spring中如何正确的使用ObjectMapper不用我再说了吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/600894.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

9. Django Admin后台系统

9. Admin后台系统 Admin后台系统也称为网站后台管理系统, 主要对网站的信息进行管理, 如文字, 图片, 影音和其他日常使用的文件的发布, 更新, 删除等操作, 也包括功能信息的统计和管理, 如用户信息, 订单信息和访客信息等. 简单来说, 它是对网站数据库和文件进行快速操作和管…

项目经理【人】任务

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 【环境】任务 【环境】绩效 【人】概述 【人】原则 【人】任务 一、定义团队的基本规则&塔克曼阶梯理论 1.1 定义团队的基本规则 1.2 塔克曼阶梯理论 二、项目经理管理风格 …

如何更好地使用Kafka? - 事先预防篇

要确保Kafka在使用过程中的稳定性,需要从kafka在业务中的使用周期进行依次保障。主要可以分为:事先预防(通过规范的使用、开发,预防问题产生)、运行时监控(保障集群稳定,出问题能及时发现&#…

UDP广播

1、UDP广播 1.1、广播的概念 广播:由一台主机向该主机所在子网内的所有主机发送数据的方式 例如 :192.168.3.103主机发送广播信息,则192.168.3.1~192.168.3.254所有主机都可以接收到数据 广播只能用UDP或原始IP实现,不能用TCP…

【Git】Git学习-09:.gitignore忽略文件

学习视频链接:【GeekHour】一小时Git教程_哔哩哔哩_bilibili 在gitignore中写入规则 在目录中创建一个名为 .gitignore 的文件 输入 vi .gitignore进入编辑模式,输入规则后保存并退出 文件里可以写文件名,可以写 *.后缀 Linux创建文件夹&…

背包问题(一维数组,二维数组,)分割等和字串

背包问题 0-1背包(i代表的是0到i任取,有不放i状态和放i状态 dp[i][j]表示,背包容量为j,可从i种物品中任选。 价值总和最大是多少!! 确定递推公式 再回顾一下dp[i][j]的含义:从下标为[0-i]的物…

Apple OpenELM设备端语言模型

Apple 发布的 OpenELM(一系列专为高效设备上处理而设计的开源语言模型)引发了相当大的争论。一方面,苹果在开源协作和设备端AI处理方面迈出了一步,强调隐私和效率。另一方面,与微软 Phi-3 Mini 等竞争对手相比&#xf…

VS2022快捷键修改

VS2022快捷键修改 VS2022快捷键修改 VS2022快捷键修改

200554-19-4,AF350琥珀酰亚胺酯具有较高的荧光量子产率

产品概述 AF350 NHS Ester,即AF350琥珀酰亚胺酯,是一种重要的荧光标记染料,具有广泛的应用领域和显著的性能特点。 中文名称:AF350琥珀酰亚胺酯 英文名称:AF350 NHS Ester,AlexaFluor350 SE CAS号&…

DI-engine强化学习入门(十又二分之一)如何使用RNN——数据处理、隐藏状态、Burn-in

一、数据处理 用于训练 RNN 的 mini-batch 数据不同于通常的数据。 这些数据通常应按时间序列排列。 对于 DI-engine, 这个处理是在 collector 阶段完成的。 用户需要在配置文件中指定 learn_unroll_len 以确保序列数据的长度与算法匹配。 对于大多数情况, learn_un…

UDP多播

1 、多播的概念 多播,也被称为组播,是一种网络通信模式,其中数据的传输和接收仅在同一组内进行。多播具有以下特点: 多播地址标识一组接口:多播使用特定的多播地址,该地址标识一组接收数据的接口。发送到多…

【知识点随笔分享 | 第十篇】快速介绍一致性Hash算法

前言: 在分布式系统中,数据的分布和负载均衡是至关重要的问题。一致性哈希算法是一种解决这些挑战的有效工具,它在分布式存储、负载均衡和缓存系统等领域得到了广泛应用。 随着互联网规模的不断扩大,传统的哈希算法在面对大规模…

大历史下的 tcp:一个松弛的传输协议

如果 tcp 是一个相对松弛的协议,会发生什么。 所谓松弛感,意思是它允许 “漏洞”,允许可靠传输的不封闭,大致就是:“不求 100% 可靠,只要 90%(或多或少) 可靠,另外 10% 的错误可检测到” or “…

STM32:配置EXTI—对射式红外传感器计次

文章目录 1、中断1.2 中断系统1.3 中断执行流程 2、STM32中断2.2EXTI(外部中断)2.3 EXTI 的基本结构2.4 AFIO复用IO口 3、NVIC基本结构3.2 NVIC优先级分组 4、配置EXTI4.2 AFIO 库函数4.3 EXTI 库函数4.4 NVIC 库函数4.5 配置EXTI的步骤4.6 初始化EXTI 1…

渗透测试流程

一、攻击流程 信息收集阶段→漏洞分析阶段→攻击阶段→后渗透阶段 二、信息收集 1、收集内容: IP资源:真实IP获取、旁站信息收集、C段主机信息收集域名发现:子域名信息收集、子域名枚举发现子域名、搜索引擎发现子域名、第三方聚合服务器发…

PyQt 入门

Qt hello - 专注于Qt的技术分享平台 Python体系下GUI框架也多了去了,PyQt算是比较受欢迎的一个。如果对Qt框架熟悉,那掌握这套框架是很简单的。 一,安装 1.PyQt5 pip3 install PyQt5 2.Designer UI工具 pip3 install PyQt5-tools 3.UI…

MFC DLL注入失败一些错误总结

使用cheat Engine为MFC窗口程序注入DLL时一定要注意,被注入的exe程序和注入的DLL 的绝对路径中一定不要带有中文字符,否则会遇到各种各样的奇怪错误,如下所示: 以下是dll绝对路径中均含有中文字符,会报错误&#xff…

【BUUCTF】Crypto_RSA(铜锁/openssl使用系列)

【BUUCTF】Crypto_RSA(铜锁/openssl使用系列) 1、题目 在一次RSA密钥对生成中,假设p473398607161,q4511491,e17 求解出d作为flga提交 2、解析 RSA加密过程: 1)选择素数:选择两个不…

python中一些莫名其妙的异常

目录 一、字符串中空格\xa0二、文件写入为空问题三、Counter对NAN空值的统计问题 一、字符串中空格\xa0 对于文本中的一些空格,原始状态时显示为普通“空格”(其实是latin1编码字符),但是经过split()操作后,这些latin…

Linux cmake 初窥【2】

1.开发背景 基于上一篇的基础上,再次升级 2.开发需求 基于 cmake 指定源文件目录可以是多个文件夹,多层目录 3.开发环境 ubuntu 20.04 cmake-3.23.1 4.实现步骤 4.1 准备源码文件 工程目录如下 顶层脚本 compile.sh 负责执行 cmake 操作&#xff0…