Почему первый алгоритм sqrt быстрее второго?

#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 раз без использования цикла, это ускорится еще больше. Но это всего лишь догадка.