static int add(int a, int b){
return a + b;
}
@Test
public void directAdd() throws Throwable {
// 编译 31ms
System.out.println(System.currentTimeMillis());
int r = 0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
r += add(i, j);
}
}
System.out.println(r);
System.out.println(System.currentTimeMillis());
}
@Test
public void directAddBoxing() throws Throwable {
// 使用 Integer,引入 boxing unboxing 开销,526ms
System.out.println(System.currentTimeMillis());
int r = 0;
for (Integer i = 0; i < 10000; i++) {
for (Integer j = 0; j < 10000; j++) {
r += add(i, j);
}
}
System.out.println(r);
System.out.println(System.currentTimeMillis());
}
@Test
public void invokeReflectionTest() throws Throwable {
// 反射 1s127ms
Method add = RuntimeOptimization.class.getDeclaredMethod("add", int.class, int.class);
System.out.println(System.currentTimeMillis());
int r = 0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
r += (int) add.invoke(null, i, j);
}
}
System.out.println(r);
System.out.println(System.currentTimeMillis());
}
@Test
public void invokeMethodHandlerTest() throws Throwable {
// MethodHandler 210ms
MethodHandle add = MethodHandles.lookup().findStatic(RuntimeOptimization.class, "add", MethodType.methodType(int.class, int.class, int.class));
System.out.println(System.currentTimeMillis());
int r = 0;
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < 10000; j++) {
r += (int) add.invokeExact(i, j);
}
}
System.out.println(r);
System.out.println(System.currentTimeMillis());
}

可见 MethodHandler 比boxing/unboxing的编译版本还要快,显然它在编译时消除了boxing开销,也就是说 invokeExact(Object...) 并不会真的 boxing,Object invokeExtract 也不返回 Object 后再 unboxing 到 int。所以不必纠结为何不提供 add.pushInt(a).pushInt(b).invoke() 这样的结构,编译器已经做了这项优化。

当然,再怎么折腾还是比编译版本慢 10 倍,目前没有更好的办法了。

MethodHandler 不会产生 boxing的更多相关文章

  1. 【C#】 装箱 (boxing) 和拆箱 (unboxing)

    目录: 1. 装箱和拆箱 2. 深入理解装箱和拆箱 3. int[] to object[],值类型数组到对象数组的转化 4. 使用泛型减少装箱和拆箱 1.  装箱和拆箱 装箱 就是把“值类型”转换成 ...

  2. Java中的boxing和unboxing(转)

    测试代码: System.out.println(0L == 0);//true System.out.println(((Long)0L).equals(0));//false Integer i1 ...

  3. [Done]FindBugs: boxing/unboxing to parse a primitive

    在开发过程中遇到了以下问题: FindBugs: boxing/unboxing to parse a primitive 查看代码(左边是老代码,右边是新的): 问题出在 自动装箱和拆箱的检查. 参 ...

  4. boxing & unboxing

    [boxing & unboxing] Boxing is the process of converting a value type to the type object or to an ...

  5. 你真的了解装箱(Boxing)和拆箱(Unboxing)吗?

    所谓装箱就是装箱是将值类型转换为 object 类型或由此值类型实现的任一接口类型的过程.而拆箱就是反过来了.很多人可能都知道这一点,但是是否真的就很了解boxing和unboxing了呢?可以看下下 ...

  6. 自动装箱(boxing)和自动拆箱(unboxing)

    摘自:http://www.codeceo.com/article/java-boxing-unboxing.html Java的四类八种基本数据类型 基本类型 占用空间(Byte) 表示范围 包装器 ...

  7. Real Boxing 2

    http://itunes.apple.com/ca/app/real-boxing-2/id932779605?mt=8&ign-mpt=uo%3D4

  8. Boxing

    测试自动装箱和自动拆箱,意思是运行的时候编译器帮我们加了两个代码: public class AutoBoxingandUnBoxing { public static void main(Strin ...

  9. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  10. .Net中的AOP系列之《方法执行前后——边界切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...

随机推荐

  1. 七张图看懂 Linux profiling 机制

    1 图 1 Linux profiling 手段一览 软件埋点: 手动埋点:主动调用 trace 函数来实现埋点. Android systrace 即是这样一个例子,如图 2 和 图 3 所示 自动 ...

  2. Gradio 5 稳定版正式发布

    在过去的几个月里,我们一直在努力工作,今天,我们想向大家展示成果:Gradio 5 稳定版现已发布. 有了 Gradio 5,开发者可以构建 生产级的机器学习 Web 应用,这些应用不仅性能优越.可扩 ...

  3. element+vue2下的input的样式修改

    /* 禁用下的input的字体颜色 */ /* .el-input.is-disabled /deep/ .el-input__inner { color: red; } */ /* 禁用下的inpu ...

  4. KubeSphere 网关的设计与实现(解读)

    作者:泓舟子,KubeSphere 后端研发工程师,云原生爱好者,现专注于云原生微服务方向. KubeSphere 中为什么需要网关? 如果需要将 K8s 集群内的服务暴露到外部访问有那些方式呢?可以 ...

  5. 华为IPv6 GRE隧道

    IPv6 over IPv4 GRE封装隧道 实验目标: 该实验参考了华为官网案例配置 https://support.huawei.com/enterprise/zh/doc/EDOC1000097 ...

  6. SpringBoot项目集成MinIO

    一.MinIO的下载安装以及基本使用 1.下载地址:https://dl.min.io/server/minio/release/windows-amd64/minio.exe 2.下载好后需要手动创 ...

  7. nginx记录日志时记录服务器响应的内容

    目前的 nginx 是不支持输出 response 报文体的 使用body_filter_by_lua来分配请求报文体给一个nginx变量.下面是一个示例 worker_processes 1; er ...

  8. 15-1 OOP概述

    目录 核心思想 继承 动态绑定 核心思想 面向对象程序设计(object-oriented programming)的核心思想是 封装:类的接口和实现分离 继承:定义相似的类型并对相似关系建模 动态绑 ...

  9. 【THUPC 2024 初赛】 E 转化

    [THUPC 2024 初赛] 转化 我都能做出来,那就是大水题了. 思路 首先我们要确定最大可以变色的球的数量 \(tot\). 有如下两个贪心步骤: 所有颜色使用分裂操作,并更新 \(a_i\). ...

  10. Python内建函数(H)

    hasattr(object, name) 说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的). 参数obj ...