JSON多层级数据自动映射值优化

news2024/11/26 10:24:51

JSON多层级数据自动映射值优化

    • Field
    • MethodHandles
    • 结果分析

Spring boot装载模板代码工程中,JSON多层级数据自动映射值只是简单封装JsonPath,对DTO的声明字段做foreach轮询,检查字段注解@JPath,然后从JsonPath的解析缓存中读取@JPath注解的映射路径值,调用ReadContext.read方法取值,按照类型设置对应字段的值;之前,寻找反射的优化时,看到过jdk7新增的MethodHandles用于优化反射,就试试用MethodHandles优化一下;反射在后续更新版本中也借鉴了MethodHandles的一些功能,性能也有一定的提升。

Field

field的set值方法根据字段查找UnsafeFieldAccessorImpl对应的类型实现方法后,在底层调用Unsafe.putObject方法。
在这里插入图片描述

MethodHandles

在原来封装的方法上做如下改动:


	static MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();

	private static <T> void setValueAdvance(Object obj, Field field, T dto) {
        try {
            field.setAccessible(true);
            MethodHandle methodHandle = publicLookup.unreflectSetter(field);
            if (obj != null) {
                if (obj instanceof String) {
                    methodHandle.invoke(dto, typeStrategyMap.get(obj.getClass()).transformType(obj, field.getType()));
                } else if (obj instanceof Map) {
                    Map value = (Map) obj;
                    Object v = JSONObject.toJavaObject(new JSONObject(value), field.getType());
                    methodHandle.invoke(dto, v);
                } else if (obj instanceof Integer) {
                    methodHandle.invoke(dto, typeStrategyMap.get(obj.getClass()).transformType(obj, field.getType()));
                } else if (obj instanceof Long) {
                    methodHandle.invoke(dto, typeStrategyMap.get(obj.getClass()).transformType(obj, field.getType()));
                } else if (obj instanceof Double) {
                    methodHandle.invoke(dto, typeStrategyMap.get(obj.getClass()).transformType(obj, field.getType()));
                } else if (obj instanceof Date) {
                    Date value = (Date) obj;
                    methodHandle.invoke(dto, value);
                } else if (obj instanceof JSONArray) {
                    JSONArray value = (JSONArray) obj;
                    if (field.getType().equals(String.class)) {
                        methodHandle.invoke(dto, value.toJSONString());
                    } else {
                        Type genericType = field.getGenericType();
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) genericType;
                            // 得到泛型里的class类型对象
                            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                            List values = com.alibaba.fastjson.JSONArray.parseArray(value.toJSONString(), actualTypeArgument);
                            methodHandle.invoke(dto, values);
                        } else {
                            methodHandle.invoke(dto, value);
                        }
                    }
                } else if (obj instanceof List) {
                    List value = (List) obj;
                    methodHandle.invoke(dto, value);
                } else if (obj instanceof JSONObject) {
                    JSONObject value = (JSONObject) obj;
                    if (field.getType().equals(String.class)) {
                        methodHandle.invoke(dto, value.toJSONString());
                    } else {
                        methodHandle.invoke(dto, value);
                    }
                } else if (obj instanceof Boolean) {
                    Boolean value = (Boolean) obj;
                    if (field.getType().equals(Integer.class)) {
                        methodHandle.invoke(dto, value ? 1 : 0);
                    } else {
                        methodHandle.invoke(dto, value);
                    }
                } else if (obj instanceof BigDecimal) {
                    methodHandle.invoke(dto, typeStrategyMap.get(obj.getClass()).transformType(obj, field.getType()));
                }
            }
        } catch (Throwable iae) {
            iae.printStackTrace();
        }
    }

使用JMH工具做测试:

/**
 * Fork 1个进程进行测试
 * 平均时间
 * JIT预热
 * 迭代10次,每次5s
 * 结果所使用的时间单位
 */
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3)
@Measurement(iterations = 10, time = 5)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Threads(10)
public class PathUtilBenchmark {

    static String DATA = "{\"reply_count\":111111,\"com\":\"OptaPlanner是一个开源的轻量级、可嵌入的约束满足引擎!!!\",\"co\":10000000,\"desc\":\"OptaPlanner是一个开源的轻量级、可嵌入的约束满足引擎,可求解规划问题,100%由Java编写,可以在任何JVM上运行,也可以在Maven中央存储库中使用、支持多种平台下载\",\"comment\":\"OptaPlanner是一个开源的轻量级、可嵌入的约束满足引擎,可求解规划问题,100%由Java编写,可以在任何JVM上运行,也可以在Maven中央存储库中使用、支持多种平台下载\"}";

    @Benchmark
    public AdvanceDTO parse() {
        return JsonPathParseUtil.Json2DTO(DATA, AdvanceDTO.class);
    }

    @Benchmark
    public AdvanceDTO parseAdvance() {
        return JsonPathParseUtil.Json2DTOAdvance(DATA, AdvanceDTO.class);
    }

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
                .include(PathUtilBenchmark.class.getSimpleName())
                .result("./result-mh-ex.json")
                .resultFormat(ResultFormatType.JSON)
                .build();
        new Runner(options).run();
    }

}


JMH在测试时,不能用debug模式运行,只能run,执行结果情况如下:
5个线程
![](https://img-blog.csdnimg.cn/53090731a66d4e6e85c0d827d891b598.png
10个线程
在这里插入图片描述
在这里插入图片描述

结果分析

从测试看,性能上确实有提升!跟踪debug:

DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);

返现都会调用Unsafe的putObject的方法,但是,MethodHandles通过LambdaForm构建, LambdaForm是MethodHandles在虚拟机下执行流程的具体实现(LambdaForm是受到lambda的启发而产生的,并不是lambda的实现方式)。非常量类型的MethodHandle 在运行时分发,但运行时分发不能被JIT优化,性能上是有所损失的。LambdaForm是用来解决这一问题的。粗略的说,LambdaForm所代表的字节码可以被JIT优化。因此在非常量类型的MethodHandle变为高性能的调用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字孪生三维可视化在海洋能源开发中的应用有哪些?

数字孪生是一种将现实世界中的实体、系统或过程在虚拟世界中重构&#xff0c;并相互映射和交互的领先技术。在能源领域&#xff0c;数字孪生技术可谓大有作为&#xff0c;比如通过实时监测和分析各种数据&#xff0c;提高能源的利用效率、降低能源成本、优化能源分配&#xff0…

【零基础入门学习Python---Python中机器学习和人工智能之快速入门实践】

&#x1f680; 零基础入门学习Python&#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜…

android_mars老师_获取用户定位

结果展示 MainActivity package com.example.locationmanager;import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint; import android.content.Context; import android.location.Location; import …

JavaWeb 笔记——3

JavaWeb 笔记——3 JavaWeb技术栈一、HTTP1.1、HTTP介绍1.2、HTTP请求数据格式1.3、HTTP响应数据格式 二、Web服务器 - Tomcat2.1、简介&基本使用2.2、Tomcat配置和部署项目2.3、Web项目结构2.4、创建MavenWeb项目2.5、IDEA集成本地Tomcat2.6、Tomcat-Tomcat Maven插件 三、…

23西安电子科技大学通信工程学院811考研录取情况

01、通信工程学院各个方向 02、23通信工程学院一志愿考研录取情况总览、平均分 PS&#xff1a;通院23年院线相对于22年院线上涨5-15分&#xff0c;个别专业下降10分反应西电通院热度23年和22年基本一致。 PS&#xff1a;1、通院23年比较多的考生在本部学硕、专硕扎堆&#xff…

【花雕】全国青少年机器人技术一级考试备考实操搭建手册6

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…

yolov7论文学习——创新点解析、网络结构图

创新点 1、提出了E-ELAN&#xff0c;但是只在yolov7-e6e中使用到。 2、yolov7基于拼接模型的缩放方法&#xff0c;在yolov7x中使用到。 3、将重参数化卷积应用到残差模块中或者用到基于拼接的模块中去。RepConvN 4、提出了两种新的标签分配方法 一、ELAN和E-ELAN 1、 ELAN …

AI 如何应对 DevOps 监控和可观察性挑战

持续监控和可观察性用例 CI异常检测&#xff1a; AI可以分析历史数据以检测持续集成阶段的异常。任何不寻常的变化都可以在进入下一阶段之前进行标记以供审查。IBM Watson AnomalyDetection 等工具可以通过使用 AI 检测模式和异常情况来帮助识别这些异常情况。 代码质量保证&…

如何快速定位linux故障

1、背景 有时候会遇到一些疑难杂症&#xff0c;并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累&#xff0c;并且有些问题涉及到的领域非常广&#xff0c;才能定位到问题。所以&#xff0c…

防火墙详解

1、什么是防火墙&#xff1f; 防火墙&#xff08; Firewall &#xff09;是防止火灾发生时&#xff0c;火势烧到其它区域&#xff0c;使用由防火材料砌的墙。 后来这个词语引入到了网络中&#xff0c;把从外向内的网络入侵行为看做是火灾&#xff0c;防止这种入侵的策略叫做防…

批量多开谷歌浏览器丨非扩展chrome浏览器实现分身多开微博 切换多个微博帐号工具

教你多开用Google 浏览器 实现Chrome怎样同时登录多个微博号 按照此教程多开后的Google浏览器可以实现相互的独立性&#xff0c;每个浏览器上收藏的书签、增加的拓展程序都可以实现独立性并可实现独立记忆性 一、安装正版Google浏览器 1&#xff1a;安装位置最好选择非C盘 二…

基于低代码平台打造的焙乐道销售支持系统

编者按&#xff1a;低代码平台说了那么多&#xff0c;在实际应用中又是怎样体现的它的种种优势呢&#xff1f;今天小编结合实际案例来说说。 本文是以最大的烘焙原料产商——焙乐道的销售支持系统为例子&#xff0c;进行说明。 客户说明&#xff1a;焙乐道是一家国际性集团公司…

凝思系统docker离线安装

# linux离线安装docker (18.03.1-ce) ## 解压&#xff0c;得到docker文件夹 tar xzvf docker-18.03.1-ce.tgz ## 将docker文件夹里面的所有内容复制到/usr/bin目录 sudo cp docker/* /usr/bin/ ## 开启docker守护进程 sudo dockerd & 当终端中显示【API list…

有参构造,无参构造,半缺省构造

目录 有参构造 无参构造 半缺省构造 有参构造 C 中的有参构造函数&#xff08;Parameterized Constructor&#xff09;是一个类中带有参数的特殊成员函数&#xff0c;用于创建对象并根据传入的参数对对象的成员进行初始化。有参构造函数在定义时需要指定参数的类型和名称&am…

相机- yolo训练集 环境搭建

一、环境准备 运行cmd执行python --version 检查是否安装成功 安装pip&#xff0c;打开运行指令 python -m ensurepip --upgrade 打开官网&#xff0c;下载get_pip.py 运行cmd 运行指令python get-pip.py 运行cmd 运行指令 pip --version 显示pip版本即安装成功 根据上面获…

Lucene介绍与入门使用

https://github.com/apache/lucene Lucene简介 Lucene是apache软件基金会4 jakarta项目组的一个子项目&#xff0c;是一个开放源代码的全文检索引擎工具包&#xff0c;但它不是一个完整的全文检索引擎&#xff0c;而是一个全文检索引擎的架构&#xff0c;提供了完整的查询引擎…

宁波阿里云代理商:阿里巴巴CEO张勇:阿里云是一家云计算产品公司

4月26日&#xff0c;在2023阿里云合作伙伴大会上&#xff0c;阿里巴巴董事会主席兼CEO、阿里云智能CEO张勇表示&#xff0c;阿里云的核心定位是一家云计算产品公司&#xff0c;生态是阿里云的根基。 张勇表示&#xff0c;当前我们正站在智能化的起点&#xff0c;这是让“被集成…

基于Python的二维码识别系统设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

基于单片机智能加湿器 水位防干烧加湿器的设计与实现

功能介绍 以51/STM32单片机作为主控系统&#xff1b;LCD1602液晶显示当前温湿度&#xff0c;当前模式&#xff0c;湿度下限;按键设置湿度下限&#xff0c;当湿度低于下限时开启加湿器;水位传感器检查加湿器是否有水&#xff0c;如果没有水到话加湿器不进行工作&#xff0c;蜂鸣…

Spring Security OAuth2.0(2):基于session的认证方式

文章目录 认证流程创建工程1 创建maven工程2. 实现认证功能3. 会话功能4. 授权功能 认证流程 \qquad 基于session的认证方式如下 \qquad 它的交互流程是&#xff0c;用户认证成功后&#xff0c;在服务端生成用户相关的数据保存在session(当前会话)中&#xff0c;发给客户端的s…