Java有执行时间下限吗?

Java有执行时间下限吗?,java,operating-system,cpu,java-bytecode-asm,Java,Operating System,Cpu,Java Bytecode Asm,我设计了一个程序,旨在测量时间消耗,同时避免系统。currentTimeMillis()微小执行的阈值(可能需要不到1毫秒的时间)(对于额外的操作,它将不可避免地产生可接受的不准确性),但是计数结果是222,无论run()方法中的语句是什么(仅限于基本算法)。我想不出任何可能的解释,听起来不可思议,但可能是执行的下限 public static void main(String[] args) throws Exception{ long result=TinyTimer(new Ru

我设计了一个程序,旨在测量时间消耗,同时避免
系统。currentTimeMillis()
微小执行的阈值(可能需要不到1毫秒的时间)(对于额外的操作,它将不可避免地产生可接受的不准确性),但是
计数
结果是222,无论
run()
方法中的语句是什么(仅限于基本算法)。我想不出任何可能的解释,听起来不可思议,但可能是执行的下限

public static void main(String[] args) throws Exception{
     long result=TinyTimer(new Runnable(){
        @Override
        public void run(){
            double d=190283758/287365628;
        }
     });
     System.out.println(result);
}

public static long TinyTimer(Runnable r){
    long count=0;
    long origin=System.currentTimeMillis();
    while(System.currentTimeMillis()==origin){
        r.run();
        count++;
    }
    return count;
}
你应该注意到

  • 在一些较旧的windows系统上,System.currentTimeMillis()的分辨率是16毫秒,而不是1毫秒
  • 尚未预热的代码的性能作为练习很有趣,但很少与生产系统相关。我建议您至少忽略前2秒的预热
  • 不起任何作用的代码可以使用死代码消除来消除。在这种情况下,您应该期望代码被消除,预热后的所有时间都是调用
    System.currentTimeMillis()
    所需的时间,这应该在25-50纳秒之间,具体取决于您的CPU
我建议您考虑使用(Java Microbenchamrk Harness),它设计用于处理编写微基准测试时的大多数常见错误

但不管run()方法中的语句是什么,计数都是222(仅限于基本算法)


很可能是运行解释器来执行此代码所花费的时间太长,而且开销太大,您选择的操作没有多大区别。

如果在方法中放入大量操作(例如Thread.sleep),我相信您可以得到少于222个操作。您可以使用System.nanoTime进行更高精度的测量。这很奇怪,我多次运行了您的代码,收到的计数从2000到700000不等。这在您尝试执行的操作中是不可预测、不可靠或不有效的。可能是因为像您在示例中编写的那样简单的操作在编译时进行了评估(因为它只使用常量)和/或完全消除(因为对计算结果不做任何处理)。操作的选择没有任何区别,因为这些操作都是在编译时进行计算的。
222
似乎非常特定于OP的环境。作为补充说明,优化器甚至可以消除
currentTimeMillis()的开销
当它理解其语义时。因此整个
TinyTimer
方法可以替换为“等待至少一毫秒并返回任意
long
值”…@Holger系统。currentTimeMillis()只能在用其他计时器替换的情况下删除。我从未见过Oracle JDK这样做。它了解有限的一组方法,但这不是其中之一。我不是说今天会发生这种情况,而是说仍然
System.currentTimeMillis()
因此,无论优化器是否知道如何删除它,优化器都必须知道它。@Holger它不能被删除,因为它返回的值是不稳定的,即它在当前线程中不做任何操作而不断变化。使用它的代码将来可能会以有趣的方式进行优化。例如,在原始代码中,Jvm可以添加一个
Thread.sleep(1);
在循环的末尾。这就是我所说的“组成一个特定的n”(注意溢出是可能的)。任何
long
数字都可以,包括负数。