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

最不常见的多种算法的速度(java),java,performance,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 test = a; true; test += a){
            if(test % b == 0)
                return test;
        }
    }

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

谢谢


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

现在评论或预测哪一部分更快还为时过早

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

在案例1中,每增加一步a

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

让我们以案例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中,您使用的是
递增运算符
,如果和
返回,则在
中相乘。
它在每个if条件下都是相乘的

增量操作可以通过使用组件的增量操作进行优化,因此它可以比使用a进行添加更快

情况1中的额外时间由a相加

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

如果乘法比加法慢,则情况2比情况1稍慢。您可能会注意到,只有在大量的测试运行中才会出现细微的差异

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


因此,在得出最终结论之前,必须对这两种代码进行分析,以了解它们在所用时间方面的差异。

粗略地说,要创建快速代码,请避免一切会导致汇编程序代码速度缓慢的事情。这包括:

  • 临时变量(此处:循环变量)

  • 常量(此处为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;
}
public intown(inta,intb){
int x=a;
对于(int y=0;x+=a){
而(y

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

这两个方法应该几乎相同——它们做的事情完全相同(正如人们所说,先优化算法,然后优化代码)。唯一的区别是第二个使用乘法和加法,这应该比第一个慢一点。在b为0的情况下,结果是一个无限循环。你是对的,忽略无用的情况是有效的。我们说的是效率而不是稳定性。嗯,第一个要求是有一个正确的程序。您可以检查循环外的参数。程序在正确的参数内是正确的。即使问题中的算法抛出b=0,您也可以向Euler自己报告;-)
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;
}