2016-09-11 83 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和服務器硬件上需要幾百納秒 - 不僅僅是從主內存中加載一些內容 - 所以最大化性能的最佳方法是儘可能緩存。但在進行更改之前和之後總是進行測量。