#java #algorithm #sqrt #jmh
#java #алгоритм #sqrt #jmh
Вопрос:
Я тестировал некоторые алгоритмы с квадратным корнем, пока не заметил, что первый метод быстрее второго
@Benchmark
@Fork(value = 1)
@BenchmarkMode(Mode.Throughput)
public void sqrt1() {
int number = 25 << 10;
int result = sqrt1(number);
}
@Benchmark
@Fork(value = 1)
@BenchmarkMode(Mode.Throughput)
public void sqrt2() {
int number = 25 << 10;
int result = sqrt2(number);
}
public static int sqrt1(int number) {
number >>= 10;
int c = 0x8000;
int g = 0x8000;
if (g * g > number) {
g ^= c;
}
c >>= 1;
if (c == 0) {
return g << 10;
}
g |= c;
for (int i = 0; i < 15; i ) {
if (g * g > number) {
g ^= c;
}
c >>= 1;
if (c == 0) {
return g << 10;
}
g |= c;
}
return g << 10;
}
public static int sqrt2(int number) {
number >>= 10;
int c = 0x8000;
int g = 0x8000;
for (int i = 0; i < 16; i ) {
if (g * g > number) {
g ^= c;
}
c >>= 1;
if (c == 0) {
return g << 10;
}
g |= c;
}
return g << 10;
}
Результаты тестов
Benchmark Mode Cnt Score Error Units
Benchmarks.sqrt1 thrpt 20 104918275,263 ± 1080520,157 ops/s
Benchmarks.sqrt2 thrpt 20 93597198,803 ± 417763,363 ops/s
Почему первый метод быстрее второго?
Тесты, выполненные с использованием jhm и java 8
-Windows 10 Home
-Intel Core I7-7700HQ@2.80GHz
-16 ГБ оперативной памяти
Комментарии:
1. черт возьми, это почти потерянный кусочек знаний о том, что вы можете выполнить это вычисление без явного умножения . Со средними современными процессорами это может быть не быстрее. Может быть, это медленнее! Но со старыми или маленькими (возможно, встроенными) процессорами, у которых нет аппаратного множителя, это может иметь большое значение.
Ответ №1:
Первый цикл выполняется только 15 раз. Второй цикл выполняется 16 раз. Итак, вы делаете на одно приращение меньше и сравниваете в первом. Я бы предположил, что если вы просто повторите вычисление 16 раз без использования цикла, это ускорится еще больше. Но это всего лишь догадка.