2016-09-11 54 views
3

Math.sin()Math.cos()等功能有多广泛? 如果您连续多次调用具有相同参数的方法,编译器是否会优化代码?如果没有,那么你应该在多少次这些方法的调用中开始将结果缓存到一个变量中?应该缓存三角函数吗?

+0

你应该让JIT担心这一点。 – Kayaman

回答

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

您可以为factorial元素保留一个运行变量,这将避免O(n^2)问题(因子本身就是O(n))。在完成之后,sin&cos可以实现O(n),其中n是精度。 – abligh

+1

你完全忽略了这里的参数减少.. – harold

1

与所有性能问题一样,您应该编写一个基准并自行查找,因为答案取决于您的JVM,操作系统和硬件。可以肯定的说Math.sin/cos在现代PC和服务器硬件上需要几百纳秒 - 不仅仅是从主内存中加载一些内容 - 所以最大化性能的最佳方法是尽可能缓存。但在进行更改之前和之后总是进行测量。