【问题标题】:Should trigonometric functions be cached?是否应该缓存三角函数?
【发布时间】:2017-01-19 05:44:50
【问题描述】:

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

【问题讨论】:

  • 你应该让 JIT 担心。

标签: java caching compiler-optimization jit


【解决方案1】:

与所有性能问题一样,您应该编写一个基准测试并自己找出答案,因为答案取决于您的 JVM、操作系统和硬件。可以肯定地说,Math.sin/cos 在现代 PC 和服务器硬件上将花费几百纳秒 - 比从主内存加载一些东西还要多 - 所以最大化性能的最佳选择是尽可能缓存。但始终在进行更改之前和之后进行测量。

【讨论】:

    【解决方案2】:

    三角函数通常实现为泰勒展开。他们很快。您可以自己编写并进行比较。

    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));
        }
    }
    

    您当然可以缓存这些值,但这些方法可能已经过优化。

    【讨论】:

    • 您可以为阶乘元素保留一个运行变量,这将避免 O(n^2) 问题(阶乘本身就是 O(n) 所写的)。完成后,sin & cos 可以实现 O(n),其中 n 是精度。
    猜你喜欢
    • 2011-11-27
    • 2013-05-04
    • 2017-02-20
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多