Alv*_*mos 6 java methods performance jvm
我在java中做了一些实验,我遇到了一件令我烦恼的事情.我已经意识到在java中,当我使用方法而不是直接代码时,处理它需要更多时间.
我有以下代码:
public static void main(String[] args) {
long nanoSeconds = System.nanoTime();
int i = foo();
System.out.println(i);
System.out.println("Elapsed Nanoseconds = " + (System.nanoTime() - nanoSeconds));
nanoSeconds = System.nanoTime();
int l = 10;
i = l;
System.out.println(i);
System.out.println("Elapsed Nanoseconds = " + (System.nanoTime() - nanoSeconds));
}
public final static int foo() {
int i = 10;
return i;
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的代码,分为两部分.第一个测量foo()的时间并显示foo()的返回值,第二个部分执行相同但不调用foo().
结果如下:
10
经过的纳秒= 601582
10
经过的纳秒= 49343
所以我的问题是,是否有办法不放松这种表现?
谢谢大家.
fge*_*fge 12
您不会以这种方式获得任何有意义的基准.
你没有考虑JIT.
该编译器不会在这方面,从很明显的人进行任何优化,除了; 当它在源代码中看到一个方法调用时,即使这个方法调用总是返回相同的值,它也会生成调用该方法的字节码; 当它看到一个常量时,它将生成一个ldc(加载常量)字节码指令.
但.
然后JIT在某个时候开始.如果它确定方法调用总是返回相同的结果,那么它将内联调用.在运行时.但这只是在执行了一定数量的代码执行后才能完成,并且如果它承认它在某些时候错过了(这是回溯),它总会有回路.
这只是一个优秀的JIT实现可以执行的优化.
你想看这个视频.简而言之:使用Oracle的JVM,优化将在一段代码至少执行10000次后开始启动 - 对于"代码段"的某些定义.
这是您在JMH上测量的代码:
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(Measure.SIZE)
@Warmup(iterations = 10, time = 100, timeUnit=MILLISECONDS)
@Measurement(iterations = 5, time = 200, timeUnit=MILLISECONDS)
@State(Scope.Thread)
@Threads(1)
@Fork(1)
public class Measure
{
public static final int SIZE = 1;
@Benchmark public int call() {
int i = foo();
return i;
}
@Benchmark public int callDisableOptimization() {
int i = fooDontInline();
return i;
}
@Benchmark public int inline() {
int i;
int l = 10;
i = l;
return i;
}
static int foo() {
int i = 10;
return i;
}
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
static int fooDontInline() {
int i = 10;
return i;
}
}
Run Code Online (Sandbox Code Playgroud)
说明:
call对应您的第一次测量,定期打电话foo();inline对应于您的第二次测量,您可以在其中内联逻辑foo()而不涉及任何调用;callDisableOptimization 在第一种情况下是一个特殊的转折,我们使用高级低级控制来禁用JVM的自动内联.这些是结果:
Benchmark Mode Samples Score Error Units
o.s.Measure.call avgt 5 1,279 ± 0,114 ns/op
o.s.Measure.inline avgt 5 1,289 ± 0,100 ns/op
o.s.Measure.callDisableOptimization avgt 5 3,167 ± 0,217 ns/op
Run Code Online (Sandbox Code Playgroud)
注意事项:
关于衡量JVM性能的方法的一些评论:
println操作一起包括在内,至少需要几微秒的时间;| 归档时间: |
|
| 查看次数: |
1528 次 |
| 最近记录: |