就性能而言,在 Java 中对多个操作执行一个 for 或每个操作执行多个 for 有什么影响?
In terms of performance, what's the impact in Java of doing one for with multiple operations or multiple fors with one operation each?
我关心的是提高源代码的可读性,它涉及通过将庞大的方法分解为更小(简洁)的方法来减少它们的大小。所以,简而言之,假设我有一个非常单一的方法,可以做很多不同的事情,例如:
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在执行或编译方面是否有一些优化?
- 我应该关心这种性能问题吗?
注意:我知道在渐近增长和大 O 符号方面我们应该忽略常量,但我只是想知道这种情况如何适用于 Java。
如果您完成 big-O 分析,您将看到两个选项都减少到 O(n)
。它们具有相同的复杂性!
它们可能不具有相同的性能,但复杂性和复杂性分析(以及 Big-O 表示法)不用于测量或预测性能。实际上,对于足够小的 n
.
值,O(n)
算法 可能 比 O(1)
算法表现更好
Does Java have some optimization in terms of execution or compiling?
是的。 JIT 编译器做了很多优化(在运行时)。但是,我们无法预测选项 1 和 2 是否具有相同的性能。
Should I be concerned with this kind of performance question?
是也不是。
这取决于性能对您的项目是否重要/有多重要。 对于许多项目1,与其他事物相比,应用程序性能并不重要;例如满足所有功能需求,始终计算正确答案,不崩溃,不丢失更新等
当性能成为一个问题时,>this< 代码片段(在代码库的数百、数千、数百万行中)不一定值得优化。并非所有代码都是平等的。如果此代码只是偶尔执行,那么对其进行优化可能对 整体 性能的影响很小。
标准口头禅是避免过早优化。等待代码运行。然后创建一个基准来衡量应用程序在实际工作 中的性能。然后分析应用程序 运行 基准以找出代码的哪些部分是性能热点...并将您的优化工作集中在热点上。
1 - 关键是必须在项目的所有其他要求和约束的背景下考虑性能。如果你太早花太多时间在性能上,你很可能会错过最后期限,等等。更不用说浪费精力优化错误的代码了。
我关心的是提高源代码的可读性,它涉及通过将庞大的方法分解为更小(简洁)的方法来减少它们的大小。所以,简而言之,假设我有一个非常单一的方法,可以做很多不同的事情,例如:
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在执行或编译方面是否有一些优化?
- 我应该关心这种性能问题吗?
注意:我知道在渐近增长和大 O 符号方面我们应该忽略常量,但我只是想知道这种情况如何适用于 Java。
如果您完成 big-O 分析,您将看到两个选项都减少到 O(n)
。它们具有相同的复杂性!
它们可能不具有相同的性能,但复杂性和复杂性分析(以及 Big-O 表示法)不用于测量或预测性能。实际上,对于足够小的 n
.
O(n)
算法 可能 比 O(1)
算法表现更好
Does Java have some optimization in terms of execution or compiling?
是的。 JIT 编译器做了很多优化(在运行时)。但是,我们无法预测选项 1 和 2 是否具有相同的性能。
Should I be concerned with this kind of performance question?
是也不是。
这取决于性能对您的项目是否重要/有多重要。 对于许多项目1,与其他事物相比,应用程序性能并不重要;例如满足所有功能需求,始终计算正确答案,不崩溃,不丢失更新等
当性能成为一个问题时,>this< 代码片段(在代码库的数百、数千、数百万行中)不一定值得优化。并非所有代码都是平等的。如果此代码只是偶尔执行,那么对其进行优化可能对 整体 性能的影响很小。
标准口头禅是避免过早优化。等待代码运行。然后创建一个基准来衡量应用程序在实际工作 中的性能。然后分析应用程序 运行 基准以找出代码的哪些部分是性能热点...并将您的优化工作集中在热点上。
1 - 关键是必须在项目的所有其他要求和约束的背景下考虑性能。如果你太早花太多时间在性能上,你很可能会错过最后期限,等等。更不用说浪费精力优化错误的代码了。