Java:空循环使用多少时间? [英] Java: how much time does an empty loop use?

查看:42
本文介绍了Java:空循环使用多少时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Java 中测试自动装箱和拆箱的速度,但是当我尝试将它与基元上的空循环进行比较时,我注意到一件奇怪的事情.这段代码:

I am trying to test the speed of autoboxing and unboxing in Java, but when I try to compare it against an empty loop on a primitive, I noticed one curious thing. This snippet:

for (int j = 0; j < 10; j++) {
    long t = System.currentTimeMillis();
    for (int i = 0; i < 10000000; i++)
        ;
    t = System.currentTimeMillis() - t;
    System.out.print(t + " ");
}

每次我运行它时,它都会返回相同的结果:

Every time I run this, it returns the same result:

6 7 0 0 0 0 0 0 0 0

为什么前两个循环总是需要一些时间,然后其余的似乎被系统跳过了?

Why does the first two loops always take some time, then the rest just seem to be skipped by the system?

在这个答案中帖子, 据说即时编译将能够优化它.但如果是这样,为什么前两个循环仍然需要一些时间?

In this answer to this post, it is said that Just-In-Time compilation will be able to optimize this away. But if so, why the first two loops still took some time?

推荐答案

JIT 在某段代码执行多次后触发.

JIT triggers AFTER a certain piece of code has been executed many times.

HotSpot JVM 将尝试识别您代码中的热点".热点是被多次执行的代码片段.为此,JVM 会计数"各种指令的执行次数,当它确定某条指令被频繁执行时,就会触发 JIT.(这是一个近似值,但这样解释很容易理解).

The HotSpot JVM will try to identify "hot spots" in your code. Hot spots are pieces of your code that are executed many many times. To do this, the JVM will "count" the executions of various instructions, and when it determines a certain piece is executed frequently, it will trigger the JIT. (this is an approximation, but it's easy to understand explained this way).

JIT(Just-In-Time)获取那段代码,并试图让它更快.

The JIT (Just-In-Time) takes that piece of code, and tries to make it faster.

JIT 用来使您的代码运行得更快的技术有很多,但最容易造成混淆的是:

The techniques used by the JIT to make your code run faster are a lot, but the one that most commonly creates confusion are :

  1. 它将尝试确定那段代码是否使用了在其他任何地方都没有使用过的变量(无用的变量),并删除它们.
  2. 如果多次获取和释放同一个锁(比如调用同一个对象的同步方法),它可以获取一次锁并在一个同步块中完成所有调用
  3. 如果您访问未声明为 volatile 的对象成员,它可以决定对其进行优化(将值放入寄存器等),从而在多线程代码中产生奇怪的结果.
  4. 它将内联方法,以避免调用成本.
  5. 它将字节码转换为机器码.
  6. 如果循环完全无用,则可以将其完全删除.

因此,对您的问题的正确答案是,空循环在经过 JIT 处理后不需要时间来执行 .. 很可能不再存在了.

So, the proper answer to your question is that an empty loop, after being JITed, takes no time to execute .. most probably is not there anymore.

同样,还有许多其他优化,但根据我的经验,这些是最令人头疼的优化之一.

Again, there are many other optimizations, but in my experience these are among those that have created most headaches.

此外,任何新版本的 Java 都在改进 JIT,有时甚至会因平台而异(因为它在某种程度上是特定于平台的).由 JIT 完成的优化很难理解,因为您通常无法使用 javap 和检查字节码找到它们,即使在 Java 的最新版本中,其中一些优化已直接移至编译器(例如,从 Java 6 开始,编译器是能够检测并警告未使用的局部变量和私有方法).

Moreover, JIT is being improved in any new version of Java, and sometimes it is even a bit different depending on the platform (since it is to some extent platform specific). Optimizations done by the JIT are difficult to understand, because you cannot usually find them using javap and inspecting bytecode, even if in recent versions of Java some of these optimizations have been moved to the compiler directly (for example, since Java 6 the compiler is able to detect and warn about unused local variables and private methods).

如果你正在编写一些循环来测试某些东西,通常最好的做法是将循环放在一个方法中,在计时之前调用该方法几次,给它一个加速"回合,然后执行定时循环.

If you are writing some loops to test something, it is usually good practice to have the loop inside a method, call the method a few times BEFORE timing it, to give it a "speed up" round, and then perform the timed loop.

这通常会在像您这样的简单程序中触发 JIT,即使不能保证它会实际触发(或者它甚至存在于某个平台上).

This usually triggers the JIT in a simple program like yours, even if there is no guarantee that it will actually trigger (or that it even exists on a certain platform).

如果您想对 JIT 或非 JIT 计时产生偏执(我做过):进行第一轮,对每次循环执行计时,并等到计时稳定(例如,与平均值的差异小于 10%)),然后从您的真实"时间开始.

If you want to get paranoid about JIT or non JIT timing (I did): make a first round, timing each execution of the loop, and wait until the timing stabilize (for example, difference from the average less than 10%), then start with your "real" timing.

这篇关于Java:空循环使用多少时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆