Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 独立于迭代次数的性能测试_Java_Performance - Fatal编程技术网

Java 独立于迭代次数的性能测试

Java 独立于迭代次数的性能测试,java,performance,Java,Performance,尝试回答此问题: 我做了一个性能测试: class A{} class B extends A{} A b = new B(); void execute(){ boolean test = A.class.isAssignableFrom(b.getClass()); // boolean test = A.class.isInstance(b); // boolean test = b instanceof A; } @Test public void testPerf()

尝试回答此问题:

我做了一个性能测试:

class A{}
class B extends A{}

A b = new B();

void execute(){
  boolean test = A.class.isAssignableFrom(b.getClass());
  // boolean test = A.class.isInstance(b);
  // boolean test = b instanceof A;
}

@Test
public void testPerf() {
  // Warmup the code
  for (int i = 0; i < 100; ++i)
    execute();

  // Time it
  int count = 100000;
  final long start = System.nanoTime();
  for(int i=0; i<count; i++){
     execute();
  }
  final long elapsed = System.nanoTime() - start;
System.out.println(count+" iterations took " + TimeUnit.NANOSECONDS.toMillis(elapsed) + "ms.);
}
class A{}
类B扩展了{}
A b=新b();
void execute(){
布尔测试=A.class.isAssignableFrom(b.getClass());
//布尔测试=A.class.isInstance(b);
//布尔测试=A的b实例;
}
@试验
公共void testPerf(){
//预热代码
对于(int i=0;i<100;++i)
执行();
//计时
整数计数=100000;
最终长启动=System.nanoTime();
对于(int i=0;i
  • 一百次迭代对于热身来说是不够的。默认的编译阈值是10000次迭代(一百次以上),所以最好至少超过这个阈值一点
  • 一旦编译被触发,世界就不会停止;编译是在后台进行的。这意味着它的效果只有在稍微延迟后才会开始被观察到
  • 有足够的空间对测试进行优化,这样整个循环都会被压缩成最终结果,这就解释了常数的原因
  • 无论如何,我总是让一个外部方法调用内部方法大约10次来进行基准测试。内部方法根据需要进行大量迭代,比如10000次或更多次,以使其运行时间上升到至少几十毫秒。我甚至不必为
    nanoTime
    操心,因为如果微秒精度对您很重要的话,这只是测量时间间隔太短的标志


    当您这样做时,您可以使JIT在内部方法的编译版本被解释版本替换后更容易地执行它。另一个好处是,您可以确保内部方法的时间稳定。

    如果您想对一个简单函数进行真正的基准测试,您应该使用micro-基准测试工具,比如。尝试创建自己的基准测试会简单得多。

    JIT编译器可以消除没有任何作用的循环。这可以在10000次迭代后触发


    我怀疑您正在计时的是JIT检测到循环没有做任何事情并将其删除所需的时间。这将比执行10000次迭代所需的时间稍长。

    您确定100000次迭代需要15毫秒吗?似乎很多…@assylias我猜他只测量了“启动时间”在JIT替换解释代码之前。我认为JIT将通过静态分析证明循环可以折叠为单个检查并编译,而无需循环。如果编译阈值为1,它将立即实现这一点。
    @Test
    public void testPerf() {
        boolean test = false;
    
        // Warmup the code
        for (int i = 0; i < 100; ++i)
            test |= b instanceof A;
    
        // Time it
        int count = Integer.MAX_VALUE;
        final long start = System.nanoTime();
        for(int i=0; i<count; i++){
            test |= b instanceof A;
        }
        final long elapsed = System.nanoTime() - start;
        System.out.println(count+" iterations took " + TimeUnit.NANOSECONDS.toMillis(elapsed) + "ms. AVG= " + TimeUnit.NANOSECONDS.toMillis(elapsed/count));
    
        System.out.println(test);
    }