【问题标题】:Is there a execution time lower limit for Java?Java有执行时间下限吗?
【发布时间】:2016-07-26 06:42:09
【问题描述】:

我设计了一个程序,旨在测量时间消耗,同时避免 System.currentTimeMillis() 微小执行的阈值(可能需要不到 1 毫秒)(对于额外的操作,它不可避免地会产生可接受的不准确性),但 count 原来是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;
}

【问题讨论】:

  • 如果你在方法中放很多操作(比如一个Thread.sleep),我相信你可以得到小于222。
  • 您可以使用 System.nanoTime 进行更高精度的测量。
  • 这很奇怪,我多次运行您的代码,收到的计数从 2,000 到 700,000 不等。
  • 这在您尝试做的事情上是不可预测的、可靠的或有效的。
  • 可能是因为像您在示例中编写的那样简单的东西是在编译时评估的(因为它只使用常量值)和/或完全消除(因为您没有对计算结果)。

标签: java operating-system cpu java-bytecode-asm


【解决方案1】:

你应该注意

  • System.currentTimeMillis() 的分辨率在某些较旧的 Windows 系统上为 16 毫秒,而不是 1 毫秒。
  • 尚未预热的代码的性能作为练习很有趣,但与生产系统很少相关。我建议您至少忽略前 2 秒的热身。
  • 可以使用死代码消除来消除不执行任何操作的代码。在这种情况下,您应该期望代码被消除,并且您在预热后的所有时间都是调用 System.currentTimeMillis() 所需的时间,这应该在 25 到 50 纳秒之间,具体取决于您的 CPU。

我建议您使用JMH (Java Microbenchamrk Harness),它旨在处理编写微基准测试中的大多数常见错误。

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

很可能会花费时间运行解释器来执行此代码,而且开销如此之高,您选择的操作并没有太大的区别。

【讨论】:

  • 操作的选择没有区别,因为这些操作都是在编译时评估的。而222 似乎非常特定于 OP 的环境。作为旁注,优化器甚至可以在理解 currentTimeMillis() 的语义时消除其开销。所以整个TinyTimer 方法可以替换为“等待至少一毫秒并返回任意long 值”……
  • @Holger 只能将 System.currentTimeMillis() 删除,前提是它被其他计时器替换。我从未见过 Oracle JDK 这样做。它了解一组有限的方法,而这不是其中之一。
  • 我并不是说今天会发生这种情况,但仍然System.currentTimeMillis() is an intrinsic function 所以优化器必须知道它,不管它是否知道如何忽略它。
  • @Holger 它不能被忽略,因为它返回的值是不稳定的,即它在当前线程中没有任何操作而不断变化。使用它的代码将来可能会以有趣的方式进行优化。例如在原始代码中,Jvm 可以在循环末尾添加Thread.sleep(1);
  • 这就是我所说的“组成一个特定的 n”(请注意溢出是可能的)。任何long 号码都可以,包括负数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 2019-07-14
  • 2011-11-26
  • 2019-07-02
相关资源
最近更新 更多