当前位置: 首页 > 知识库问答 >
问题:

在性能方面,在Java做一个for多个操作或多个for每个操作一个操作有什么影响?

汪阳辉
2023-03-14

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

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指令转换为iterable的。因此,我的问题是:

  1. Java在执行或编译方面是否有一些优化?
  2. 我应该关心这种性能问题吗?

注:我知道,在渐近增长和大O符号方面,我们应该忽略常量,但我只是想知道,这种情况如何适用于Java。

共有1个答案

令狐辉
2023-03-14

如果您完成了big-O分析,您将看到所有3个选项都简化为O(n)。它们有相同的复杂性!

它们很可能没有相同的性能,但复杂性和复杂性分析(和大-O符号)不是为了测量或预测性能。

Java在执行或者编译方面有没有一些优化?

是的。JIT编译器(在运行时)进行了大量优化。但是,我们无法预测选项1和选项2是否会有相当的性能。

我应该关心这种表现问题吗?

是和不是。

这取决于性能对应用程序是否重要。对于许多应用程序来说,性能与其他东西相比是不重要的;例如获得正确答案、不崩溃、不丢失更新等。

而且当性能是一个关注的问题时,不一定是>this<值得优化的代码。并非所有代码都是相等的。如果此代码只是偶尔执行,那么对其进行优化很可能对整体性能产生最小的影响。

标准的口头禅是避免过早的优化。等到代码正常工作。然后创建一个基准来测量应用程序在实际工作中的性能。然后对运行基准测试的应用程序进行分析,找出代码的哪些部分是性能热点...并将您的优化工作集中在热点上。

 类似资料:
  • 问题内容: 我正在尝试使用ADO一次在MS Access中创建多个表。是否可以在一个操作中执行多个语句?例如: 尽管每个create语句都可以完美地独立工作,但由于导致此操作失败。有没有办法做这种事情?也将有添加约束,添加索引等的语句,我真的很希望能够做到这一点,这样我就不必将字符串分成单独的部分。 问题答案: ADO to MS Access不支持批处理SQL语句。您需要将每个语句作为单独的执行

  • 在特定的活动流下,我无法将意图交付给:这是一个场景: 考虑3个活动,Home、B和C。C有两个片段CF1和CF2 B、 CF1和CF2使用相同的IntentService类,但操作不同 IntentService开始使用。(getActivity()。片段的startService(意图) 无论IntentService在哪里启动,如果它在Activity/Fragment的中运行,我都会使用来确

  • 我正在开发一个Windows服务应用程序。NET,它执行许多功能(它是一个WCF服务主机),其中一个目标是运行调度的任务。 我选择创建System.Threading。每个操作的计时器,dueTime设置为下一次执行,并且没有时段以避免重新进入 每次操作结束时,都会更改dueTime以匹配下一次计划执行。 大多数操作计划每分钟运行一次,不是一起运行,而是彼此延迟几秒钟。 现在,在添加了一些操作(大

  • PFMERGE destkey sourcekey [sourcekey ...] 将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有给定 HyperLogLog 进行并集计算得出的。 命令的复杂度为 O(N) , 其中 N 为被合并的 HyperLogLog 数量, 不过这个命令的常数复杂度比较高。

  • 问题内容: 在python 2.6中,我想对每个字典值执行一个运算,例如,我想对每个字典值乘以2。如何为该任务减少编码? 问题答案:

  • 所以我的问题是: 在这个苹果案例中,如何设计一组优雅的RESTful API,让后端轻松处理它。