时间复杂度—就性能而言,在java中,使用多个操作执行一个for或使用每个操作执行多个fors有什么影响?

gojuced7  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(241)

我关心的是提高源代码的可读性,它涉及到通过将大型方法分解为更小(简洁)的方法来减小它们的大小。简单地说,我有一个非常单一的方法,可以做很多不同的事情,例如:

public void verHugeMethod(List<Person> people) {
    for (Person person : people) {
        totalAge += person.getAge();
        totalHeight += person.getHeight();
        totalWeight += person.getWeight();
        // More calculations over class variables...
    }
}

我想把方法改成:

public void calculateTotalAge(List<Person> people) {
    for (Person person : people) {
        totalAge += person.getAge();
    }
}

public void calculateTotalHeight(List<Person> people) {
    for (Person person : people) {
        totalHeight += person.getHeight();
    }
}

public void calculateTotalWeight(List<Person> people) {
    for (Person person : people) {
        totalWeight += person.getWeight();
    }
}
// More calculations over class variables...

我关心的是应用这种重构时的性能(时间和内存)。对于一小部分人来说,这当然不是问题,但我担心这个名单会逐渐增长。
例如,对于一个更老式的 for 我可以看到以下影响:

// OPTION 1
public void method1() { // O(1) + O(3n)
    int i = 0; // O(1)
    while (int i < people.size()) { // O(n)
        doSomething(people.get(i)); // O(1)
        doAnotherThing(people.get(i)); // O(1)
        i++; // O(1)
    }
}

// OPTION 2
public void method1() { // O(2) + O(4n)
    method1(); // O(1) + O(2n)
    method2(); // O(1) + O(2n)
}
public void method2() { // O(1) + O(2n)
    int i = 0; // O(1)
    while (int i < people.size()) { // O(n)
        doSomething(people.get(i)); // O(1)
        i++; // O(1)
    }
}
public void method3() { // O(1) + O(2n)
    int i = 0; // O(1)
    while (int i < people.size()) { // O(n)
        doAnotherThing(people.get(i)); // O(1)
        i++; // O(1)
    }
}

我知道java如何将foreach指令转换为 iterables . 因此,我的问题是:
java在执行或编译方面是否有一些优化?
我应该关心这种性能问题吗?
注意:我知道在渐近增长和big-o表示法方面我们应该忽略常量,但我只是想知道这种场景是如何应用于java的。

zwghvu4y

zwghvu4y1#

如果您完成big-o分析,您将看到这两个选项都减少到 O(n) . 它们有相同的复杂性!
它们可能没有相同的性能,但是复杂性和复杂性分析(以及big-o表示法)不是用来度量或预测性能的。事实上,一个 O(n) 算法可能比 O(1) 足够小的 n .
java在执行或编译方面是否有一些优化?
对。jit编译器(在运行时)进行了大量优化。但是,我们无法预测选项1和选项2是否具有相同的性能。
我应该关心这种性能问题吗?
是和否。
这取决于性能对项目是否/有多重要。对于许多项目1,应用程序性能与其他项目相比并不重要;e、 g.满足所有功能要求,始终计算正确答案,不崩溃,不丢失更新等。
当性能是一个问题时,这段代码(在代码库的成百上千行中)不一定值得优化。并非所有的代码都是相等的。如果此代码只是偶尔执行,那么优化它可能对整体性能的影响最小。
标准准则是避免过早优化。等到你的代码运行起来。然后创建一个基准来衡量应用程序在实际工作中的性能。然后分析运行基准测试的应用程序,找出代码的哪些部分是性能热点。。。并将优化工作集中在热点上。
1-关键是性能必须在项目的所有其他要求和约束条件下考虑。如果你在表现上花太多时间,太早,你很可能错过最后期限,等等。更不用说把精力浪费在优化错误的代码上了。

相关问题