为什么使用几个“或”语句的代码比在Java中使用查找表稍快?

在我看到昨天(这里)提出的一个微观优化问题时,我发现了一些奇怪的东西:Java中的一个语句or一个语句的运行速度比在一个布尔数组中查找布尔值要快一些。

在我的测试中,对于从0到10亿的long值运行以下算法,alg1快2%左右。 (我改变了算法的测试顺序,并且得到了相同的结果)。 我的问题是: 为什么alg1更快? 我希望alg2稍快一些,因为它使用查找表,而alg1必须对75%的输入执行4次比较和3次操作。

private final static boolean alg1(long n)
{
  int h = (int)(n & 0xF);
  if(h == 0 || h == 1 || h == 4 || h == 9)
  {
    long tst = (long)Math.sqrt(n);
    return tst*tst == n;
  }  
  return false;

}

private final static boolean[] lookup = new boolean[16];
static
{
  lookup[0] = lookup[1] = lookup[4] = lookup[9] = true;
}
private final static boolean alg2(long n)
{
  if(lookup[(int)(n & 0xF)])
  {
    long tst = (long)Math.sqrt(n);
    return tst*tst == n;
  }
  else
    return false;
}

如果你很好奇,这段代码正在测试一个数字是否是一个完美的正方形,并且利用了这个事实:完美的正方形必须以十六进制的0,1,4或9结尾。


加载一些随机的数据通常比一些非分支代码慢。

当然,这一切都取决于处理器架构。 你的第一条if语句可以作为四条指令来实现。 第二个可能需要空指针检查,边界检查以及加载和比较。 另外,更多的代码意味着更多的编译时间,更多机会以某种方式阻碍优化。


我猜想问题在于数组的范围检查以及数组查找是否作为方法调用实现的。 这肯定会掩盖4连续的整数比较。 你看过字节码吗?


根据这篇文章,访问数组元素是“访问非数组元素的2到3倍”。 你的测试表明差异可能会更大。

链接地址: http://www.djcxy.com/p/15191.html

上一篇: Why is this code with several "or" statements slightly faster than using a lookup table in Java?

下一篇: Does Java JIT cheat when running JDK code?