java lang类直接调用_是否有可能使java.lang.invoke.MethodHandle与直接调用一样快?

我正在比较MethodHandle :: invoke和直接静态方法invokation的性能.这是静态方法:

public class IntSum {

public static int sum(int a, int b){

return a + b;

}

}

这是我的基准:

@State(Scope.Benchmark)

public class MyBenchmark {

public int first;

public int second;

public final MethodHandle mhh;

@Benchmark

@OutputTimeUnit(TimeUnit.NANOSECONDS)

@BenchmarkMode(Mode.AverageTime)

public int directMethodCall() {

return IntSum.sum(first, second);

}

@Benchmark

@OutputTimeUnit(TimeUnit.NANOSECONDS)

@BenchmarkMode(Mode.AverageTime)

public int finalMethodHandle() throws Throwable {

return (int) mhh.invoke(first, second);

}

public MyBenchmark() {

MethodHandle mhhh = null;

try {

mhhh = MethodHandles.lookup().findStatic(IntSum.class, "sum", MethodType.methodType(int.class, int.class, int.class));

} catch (NoSuchMethodException | IllegalAccessException e) {

e.printStackTrace();

}

mhh = mhhh;

}

@Setup

public void setup() throws Exception {

first = 9857893;

second = 893274;

}

}

我得到以下结果:

Benchmark Mode Cnt Score Error Units

MyBenchmark.directMethodCall avgt 5 3.069 ± 0.077 ns/op

MyBenchmark.finalMethodHandle avgt 5 6.234 ± 0.150 ns/op

MethodHandle有一些性能下降.

使用-prof perfasm运行它会显示:

....[Hottest Regions]...............................................................................

31.21% 31.98% C2, level 4 java.lang.invoke.LambdaForm$DMH::invokeStatic_II_I, version 490 (27 bytes)

26.57% 28.02% C2, level 4 org.sample.generated.MyBenchmark_finalMethodHandle_jmhTest::finalMethodHandle_avgt_jmhStub, version 514 (84 bytes)

20.98% 28.15% C2, level 4 org.openjdk.jmh.infra.Blackhole::consume, version 497 (44 bytes)

据我所知,基准测试结果的原因是最热区域2 org.sample.generated.MyBenchmark_finalMethodHandle_jmhTest :: finalMethodHandle_avgt_jmhStub包含由JHM循环内的MethodHandle :: invoke执行的所有类型检查.程序集输出片段(省略一些代码):

....[Hottest Region 2]..............................................................................

C2, level 4, org.sample.generated.MyBenchmark_finalMethodHandle_jmhTest::finalMethodHandle_avgt_jmhStub, version 519 (84 bytes)

;...

0x00007fa2112119b0: mov 0x60(%rsp),%r10

;...

0x00007fa2112119d4: mov 0x14(%r12,%r11,8),%r8d ;*getfield form

0x00007fa2112119d9: mov 0x1c(%r12,%r8,8),%r10d ;*getfield customized

0x00007fa2112119de: test %r10d,%r10d

0x00007fa2112119e1: je 0x7fa211211a65 ;*ifnonnull

0x00007fa2112119e7: lea (%r12,%r11,8),%rsi

0x00007fa2112119eb: callq 0x7fa211046020 ;*invokevirtual invokeBasic

;...

0x00007fa211211a01: movzbl 0x94(%r10),%r10d ;*getfield isDone

;...

0x00007fa211211a13: test %r10d,%r10d

;jumping at the begging of jmh loop if not done

0x00007fa211211a16: je 0x7fa2112119b0 ;*aload_1

;...

在调用invokeBasic之前,我们执行类型检查(在jmh循环内),这会影响输出avgt.

问题:为什么不是所有类型检查都移出循环之外?我宣布公开最终MethodHandle mhh;在基准内部.所以我希望编译器可以解决它并消除相同的类型检查.如何消除相同的类型检查?可能吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值