首页 > 编程语言 > ReflectASM高性能反射Java库

ReflectASM高性能反射Java库

时间:2023-04-07 22:11:37浏览次数:41  
标签:反射 Java String 高性能 User reflectasm com ReflectASM user

1. 简介

  在日常开发中,经常需要使用反射操作类中的属性或方法。ReflectASM是一个非常小的 Java 库,它提供高性能反射能力。
  Github地址:https://github.com/EsotericSoftware/reflectasm

2. 官方性能报告



3. 用法

ReflectASM仅可访问public属性和方法。

  • pom引入依赖
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>reflectasm</artifactId>
    <version>{latest.version}</version>
</dependency>
  • 使用 ReflectASM 的构造函数反射:
ConstructorAccess<User> constructorAccess = ConstructorAccess.get(User.class);
User user = constructorAccess.newInstance();
  • 使用 ReflectASM 的属性反射:
User user = new User();
FieldAccess fieldAccess = FieldAccess.get(User.class);
fieldAccess.set(user, "username", "张三");
String name = (String) fieldAccess.get(user, "username");
  • 使用 ReflectASM 的方法反射:
User user = new User();
MethodAccess methodAccess = MethodAccess.get(User.class);
methodAccess.invoke(user, "setUserame", "张三");
String username = (String) methodAccess.invoke(user, "getUsername");
  • 使用 ReflectASM 的属性索引反射(推荐):
User user = new User();
FieldAccess fieldAccess = FieldAccess.get(User.class);
int index = fieldAccess.getIndex("username");
fieldAccess.set(user, index, "张三");
String username = (String) fieldAccess.get(user, index);
  • 使用 ReflectASM 的方法索引反射(推荐):
User user = new User();
MethodAccess methodAccess = MethodAccess.get(User.class);
int setIndex = methodAccess.getIndex("setUserame");
int getIndex = methodAccess.getIndex("getUsername");
methodAccess.invoke(user, setIndex, "张三"
String username = (String) methodAccess.invoke(user, getIndex);

4. 单元测试

import com.esotericsoftware.reflectasm.ConstructorAccess;
import com.esotericsoftware.reflectasm.FieldAccess;
import com.esotericsoftware.reflectasm.MethodAccess;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;

/**
 * 高性能反射Java库 单元测试
 *
 * @author CL
 */
@Slf4j
public class ReflectAsmTest {

    /**
     * 测试方案:循环 n 次,通过set方法设置值,然后通过get方法获取值<br/>
     */
    @Test
    public void test() throws Exception {
//        final String FIELD_NAME = "username";
        final String SET_METHOD_NAME = "setUsername";
        final String GET_METHOD_NAME = "getUsername";
        // 次数
        int n = 1_0000;

        StopWatch stopWatch = new StopWatch();

        stopWatch.start("Java反射");

        Class<User> clazz = User.class;
//        Field field = clazz.getDeclaredField(FIELD_NAME);
//        field.setAccessible(true);
        Method setMethod = clazz.getDeclaredMethod(SET_METHOD_NAME, String.class);
        Method getmethod = clazz.getDeclaredMethod(GET_METHOD_NAME);

        for (int i = 1; i <= n; i++) {
            User user = clazz.newInstance();

            setMethod.invoke(user, "方法" + i);

            Object invoke = getmethod.invoke(user);
//            log.debug("get值:{}", invoke);
        }

        stopWatch.stop();

        stopWatch.start("ReflectAsm反射");

        ConstructorAccess<User> constructorAccess = ConstructorAccess.get(User.class);
        FieldAccess fieldAccess = FieldAccess.get(User.class);
        MethodAccess methodAccess = MethodAccess.get(User.class);

        for (int i = 1; i <= n; i++) {
            User user = constructorAccess.newInstance();

            methodAccess.invoke(user, SET_METHOD_NAME, "方法" + i);

            Object invoke = methodAccess.invoke(user, GET_METHOD_NAME);
//            log.debug("get值:{}", invoke);
        }

        stopWatch.stop();

        stopWatch.start("ReflectAsm反射(优化)");

        int setIndex = methodAccess.getIndex(SET_METHOD_NAME);
        int getIndex = methodAccess.getIndex(GET_METHOD_NAME);
        for (int i = 1; i <= n; i++) {
            User user = constructorAccess.newInstance();

            methodAccess.invoke(user, setIndex, "方法" + i);

            Object invoke = methodAccess.invoke(user, getIndex);
//            log.debug("get值:{}", invoke);
        }

        stopWatch.stop();

        for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) {
            log.info("{} 耗时:{} ms", taskInfo.getTaskName(), taskInfo.getTimeMillis());
        }
    }
    
}

class User {

    private String username;

    public User() {
    }

    public User(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

}

  100次循环单元测试结果:

23:54:37.630 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:3 ms
23:54:37.635 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:21 ms
23:54:37.635 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:0 ms

  1000次循环单元测试结果:

23:55:07.161 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:7 ms
23:55:07.168 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:35 ms
23:55:07.168 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:1 ms

  10000次循环单元测试结果:

23:55:27.604 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - Java反射 耗时:44 ms
23:55:27.611 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射 耗时:49 ms
23:55:27.611 [main] INFO com.c3stones.reflectasm.ReflectAsmTest - ReflectAsm反射(优化) 耗时:7 ms

标签:反射,Java,String,高性能,User,reflectasm,com,ReflectASM,user
From: https://www.cnblogs.com/cao-lei/p/17297207.html

相关文章

  • 【Java 并发】【九】【AQS】【八】ReentrantReadWriteLock 读写锁怎么表示
    1 前言接下来我们来看看ReentrantReadWriteLock读写锁,也是基于之前讲解的AQS来实现的,建立在AQS体系之上的一个并发工具类,这个锁很重要,在很多开源的中间件中使用的非常广泛,很多场景使用它来减少并发操作中的锁冲突,提升并发能力。2  ReentrantReadWriteLock介绍ReentrantRead......
  • Java入门
    一、Java特性和优势1.简单性:不用像C语言那样引用头文件,抛弃了指针2.面向对象3.可移植性:可以跨平台移植,一次编写多次运行4.高性能:即时编译5.分布式6.动态性:反射机制7.多线程8.安全性9.健壮性二、Java三大版本1.JavaSE:标准版(桌面开发,控制台开发等)2.JavaME:嵌入式开发(......
  • Java ClickHouse整合—官方教程
    一、开发环境OpenJDK版本>=17ClickHouse:20.7+ 1、支持的数据类型FormatSupportCommentAggregatedFunction❌limitedto groupBitmap,andknowntohaveissuewith64bitbitmapArray(*)✅Bool✅Date*✅DateTime*✅Decimal*✅SEToutput_format_decimal_trailing_zeros=1 in......
  • Java学习路径
    一、Java学习路径   1.JavaSE  2.数据库   3.前端  4.JavaWeb  5.SSM框架  6.Linux  7.SpringBoot  8.SpringCloud  9.Hadoop......
  • [Javascript] Improve performance of Array.reduce
    Comparetwocodesnippetconstpeople=[{id:1,name:'John',age:45},{id:2,name:"Op",age:32},{id:3,name:"Wade",age:39}]//option1constres=people.reduce((acc,curr)=>{return({......
  • JAVA - 面向对象编程
    面向对象是在之前基本实现的基础上的又一抽象,这里的“高内聚,低耦合”体现的更加明显,有抽丝剥茧、不断总结的感觉了。学习的时候真的会有拨开云雾见月明的感觉,这种感觉真的会上瘾。你慢慢发现所有的东西都在以自己的规律运转,发现验证使用,真的很有《实践论》的味道。我能做些......
  • java -- Math、BigInteger、BigDecimal类和基本类型的包装类、正则表达式
    Mathjava.lang.Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。Math.PI//静态常量publicstaticfinaldoublePI=3.14159265358979323846;abs//返回参数的绝对......
  • Java多版本切换 8-11-17
    Java版本切换在A:\DevEnvironment\javaVersion目录下,创建Windows命令脚本Java8.bat @echooff setJAVA_HOME=A:\DevEnvironment\jdk-1.80_152 setPath=%JAVA_HOME%\bin;%Path% echoVersionhasbeenswitchedtoJava8.Java11.bat @echooff setJAVA_HOME=A:\DevE......
  • 【开源免费】ChatGPT-Java版SDK重磅更新至1.0.10版,支持Tokens计算,快来一键接入。
    简介ChatGPTJava版SDK开源地址:https://github.com/Grt1228/chatgpt-java,目前收获将近1000个star。有bug欢迎朋友们指出,互相学习,所有咨询全部免费。最新版:1.0.10<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version......
  • salesforce学习笔记(3-1)- JavaScript Promise(LWC)
    在JS代码中,Promise到底有什么作用?首先,我们知道的是,Javascript是单线程的,什么意思呢?就是说JS在同一时间只能做一个操作,代码的执行是一行一行进行的:  这种执行方式带来的问题就是在我们打开某个画面的时候,画面可能会卡住转圈、加载中状态很久,用户体验感很差。Promise可用于......