最常见的多种算法的速度(java)

时间:2013-11-26 05:08:58

标签: java performance

我正在努力解决欧拉问题:现在我的速度定义步骤是计算两个数字的最小公倍数。那么,这些方法中哪一个更快?为什么呢?

    public static int lcm(int a, int b){
        for(int test = a; true; test += a){
            if(test % b == 0)
                return test;
        }
    }

    public static int lcm(int a, int b){
        for(int i = 1; true; i++){
            if(i*a % b == 0)
                return i*a;
        }
    }

我认为这里的基本问题是哪一个是更快的过程,乘法或加法。

感谢。

(在让我展示其余代码/说我不应该专注于我的程序的这一部分之前:我的问题不是如何得到问题的答案,而是如何使这部分更快。)

2 个答案:

答案 0 :(得分:1)

粗略地说,要创建快速代码,避免一切会导致汇编程序代码变慢的问题。这包括:

  • Temporaries(此处:循环变量)

  • 常数(此处:true)

  • 条件检查(此处:true)

  • 乘法(此处:i * a)

  • 模数(此处:测试%b)

  • 不要依赖编译器优化

临时,模数和一个比较是算法固有的,因此是不可避免的。所以它会产生这样的结果:

public int euler(int a, int b) {
    int test = a;
    while (test % b != 0) {
        test += a;
    }
    return test;
}

如果你稍微修改(数字)算法到等效方程,你可以完全消除乘法:

public int own(int a, int b) {
    int x = a;
    for (int y = 0;; x += a) {
        while (y < x) {
            y += b;
        }
        if (x == y)
            break;
    }
    return x;
}

顺便说一下:如果您要找到大数的LCM,也许您最好使用Euclid的GCD算法。因此,LCM(a,b)= a * b / GCD(a,b)。 Java类BigInteger.gcd()中已经有了一个有效的实现。

答案 1 :(得分:0)

评论或预测哪一个更快,现在为时尚早。

您的两个程序将采用相同数量的迭代,如下所述。

在案例1中,您将每步增加一个。

在案例2中,您将倍数增加1,与增加倍数相同。

让我们来看案例1

public static int lcm(int a, int b){
    for(int test = a; true; test += a){
        if(test % b == 0)
            return test;
    }
}

您已在if语句和return中避免了乘法运算。

在案例2中,您使用increment operator并在ifreturn中相乘。 它在每个if条件下相乘。

通过使用汇编的递增操作可以优化递增操作,因此它可以比通过a添加更快。

案例1中的额外时间由a。

添加

在案例2中,案例2中的额外时间是递增的,并且在每个if条件和在成功条件下的返回时相乘。

如果乘法比加法慢,则情况2稍微慢于情况1.您可能会注意到仅在大量试运行时略有差异。

请注意,还有其他因素会影响性能。

因此,在得出最终结论之前,必须对两个代码进行分析,以查看所用时间的差异。