Вам понадобится лучший тест, чем тот, который указан в вашем ответе.
Давайте посмотрим на код цикла:
for (int i = 0; i < N; i++) {
final int idx = i % NUM_SQUARES;
final long value = 1L << idx;
sum += value;
}
Сдвиг - это действительно быстрая операция для процессора -это должно быть по крайней мере так же быстро, как ++
или +=
.Поэтому, если мы посмотрим на код, у нас есть счетчик циклов (i++
), sum +=
и ветвь (i < N
).%
, вероятно, занимает в 10-20 раз больше циклов ЦП, чем сдвиг.
Так что для лучшего тестирования и синхронизации операции сдвига я бы удалил %
и получил бы все 64 степени двух внутрицикл в случайном порядке (для массива).Примерно так:
for (int i = 0; i < N; i++) {
sum += 1L << 4;
sum += 1L << 7;
sum += 1L << 1;
// and so on
}
Для версии массива вы можете использовать:
for (int i = 0; i < N; i++) {
sum += POWER_OF_TWOS[4];
sum += POWER_OF_TWOS[7];
sum += POWER_OF_TWOS[1];
// and so on
}
Или использовать переменные вместо констант и битовую маску вместо%:
for (int i = 0; i < N; i++) {
final int idx = i & 0x3f;
sum += 1L << idx;
}
for (int i = 0; i < N; i++) {
final int idx = i & 0x3f;
sum += POWER_OF_TWOS[idx];
}
Или, если оптимизатор может быть обманут с этим:
for (int i = 0; i < N; i++) {
final int idx = 0;
sum += 1L << (idx + 4);
sum += 1L << (idx + 17);
// ...
}
В любом случае, операция сдвига действительно быстра и должна быть легкой в использовании для массива с предкомпьютерными значениями.