Насколько обширны такие функции, как Math.sin()
, Math.cos()
и т. Д.? Компилятор оптимизирует код, если вы вызываете метод с теми же аргументами несколько раз подряд? Если нет, то на сколько вызовов этих методов вы должны начать кэширование результата в переменной?Должны ли кэшироваться тригонометрические функции?
3
A
ответ
1
Тригонометрические функции обычно реализуются как разложения Тейлора. Они быстры. Вы можете написать свой собственный и сравнить.
public class Main{
private static double factorial(double n) {
if (n <= 1) // base case
return 1;
else
return n * factorial(n - 1);
}
private static double sin(int n) {
int PRECISION = 10;
double rad = n*1./180.*Math.PI;
double sum = rad;
for (int i = 1; i <= PRECISION; i++) {
if (i % 2 == 0)
sum += Math.pow(rad, 2*i+1)/factorial(2 * i + 1);
else
sum -= Math.pow(rad, 2*i+1)/factorial(2 * i + 1);
}
return sum;
}
public static void main(String []args){
System.out.println(sin(180));
System.out.println(Math.sin(Math.PI));
System.out.println(sin(90));
System.out.println(Math.sin(Math.PI/2));
System.out.println(sin(200));
System.out.println(Math.sin(200*2*Math.PI/360));
}
}
Конечно, вы можете кэшировать значения, но эти методы, вероятно, будут уже оптимизированы.
1
Как и во всех вопросах производительности, вы должны написать тест и узнать сами, поскольку ответ будет зависеть от вашего JVM, ОС и оборудования. Вероятно, можно с уверенностью сказать, что Math.sin/cos займет несколько сотен наносекунд на современном ПК и серверном оборудовании - больше, чем что-то загружает из основной памяти, поэтому лучше всего максимизировать производительность - это кешировать, когда это возможно. Но всегда измеряйте до и после внесения изменений.
Вы должны позволить JIT беспокоиться об этом. – Kayaman