Рассматривая вопрос микро-оптимизации, который я вчера спросил (здесь), я нашел что-то странное: оператор or в Java работает немного быстрее, чем поиск булевого значения в массиве логических значений.
В моих тестах, используя приведенные ниже алгоритмы на значениях long от 0 до 1 миллиарда, alg1 примерно на 2% быстрее. (Я изменил порядок, в котором тестируются алгоритмы, и получаю те же результаты). Мой вопрос:  Почему alg1 быстрее? Я бы ожидал, что alg2 будет немного быстрее, так как он использует таблицу поиска, тогда как alg1 должен выполнить 4 сравнения и 3 или операции для 75% входов.
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 в шестнадцатеричном формате.