与迭代次数无关的性能测试 [英] Performance test independent of the number of iterations

查看:77
本文介绍了与迭代次数无关的性能测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图回答这张票:有什么区别在 instanceof 和 Class.isAssignableFrom(...) 之间?

我做了一个性能测试:

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.);
}

这给了我:

  • A.class.isAssignableFrom(b.getClass()):100000 次迭代用了 15 毫秒
  • A.class.isInstance(b):100000 次迭代用了 12 毫秒
  • b instanceof A:100000 次迭代用了 6ms
  • A.class.isAssignableFrom(b.getClass()) : 100000 iterations took 15ms
  • A.class.isInstance(b) : 100000 iterations took 12ms
  • b instanceof A : 100000 iterations took 6ms

但是玩迭代次数,我可以看到性能是恒定的.对于 Integer.MAX_VALUE :

But playing with the number of iterations, I can see the performance is constant. For Integer.MAX_VALUE :

  • A.class.isAssignableFrom(b.getClass()):2147483647 次迭代用了 15 毫秒
  • A.class.isInstance(b):2147483647 次迭代花费 12 毫秒
  • b 实例 A:2147483647 次迭代花费了 6 毫秒
  • A.class.isAssignableFrom(b.getClass()) : 2147483647 iterations took 15ms
  • A.class.isInstance(b) : 2147483647 iterations took 12ms
  • b instanceof A : 2147483647 iterations took 6ms

以为是编译器优化(我用JUnit运行了这个测试),我把它改成了这样:

Thinking it was a compiler optimization (I ran this test with JUnit), I changed it into this :

@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);
}

但性能仍然独立"于迭代次数.有人可以解释这种行为吗?

But the performance is still "independent" of the number of iterations. Could someone explain that behavior ?

推荐答案

JIT 编译器可以消除无用的循环.这可以在 10,000 次迭代后触发.

The JIT compiler can eliminate loops which don't anything. This can be triggered after 10,000 iterations.

我怀疑您正在计时的是 JIT 需要多长时间才能检测到循环没有执行任何操作并将其删除.这将比执行 10,000 次迭代所需的时间长一点.

What I suspect you are timing is how long it takes for the JIT to detect that the loop doesn't do anything and remove it. This will be a little longer than it takes to do 10,000 iterations.

这篇关于与迭代次数无关的性能测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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