Я ищу самый быстрый способ свернуть двойной (double d
). До сих пор я придумал два подхода:
1. d*d
2. Math.pow(d, 2)
Чтобы проверить производительность, я установил три тестовых примера: в каждом я генерирую случайные числа, используя одно и то же семя для трех случаев, и просто вычислил квадрат числа в цикле 100 000 000 раз.
В первом тестовом случае номера генерируются с использованием random.nextDouble()
, во втором случае используется random.nextDouble()*Double.MAX_VALUE
, а в третьем - с помощью random.nextDouble()*Double.MIN_VALUE
.
Результаты нескольких прогонов (приблизительные результаты, всегда есть некоторые варианты, запускаются с использованием java 1.8, скомпилированные для java 1.6 на Mac OSX Mavericks)
Approach | Case 1 | Case 2 | Case 3
---------•--------•--------•-------
1 | ~2.16s | ~2.16s | ~2.16s
2 | ~9s | ~30s | ~60s
Похоже, что вывод 1 является более быстрым, но также и тем, что Math.pow
, кажется, ведет себя странно.
У меня есть два вопроса:
1 Почему Math.pow
настолько медленный, и почему он плохо справляется с > 1
и еще хуже с < -1
номерами?
2 Есть ли способ повысить производительность по сравнению с тем, что я предложил в качестве подхода 1? Я думал о чем-то вроде:
long l = Double.doubleToRawLongBits(d);
long sign = (l & (1 << 63));
Double.longBitsToDouble((l<<1)&sign);
Но это а) неправильно, и б) примерно с той же скоростью, что и подход 1.