我有以下代码段
// List of persons with name and age
List<Person> persons = new ArrayList<>();
// Adding 10,000 objects
for(int i = 0 ; i < 10000 ; i ++) {
Person p = new Person();
p.setName("Person " + i);
p.setAge(i);
persons.add(p);
}
long time1 = System.nanoTime();
System.out.println("Time before steram.reduce()" + time1);
Optional<Person> o1 = Optional<Person> o1 = persons.stream().reduce(BinaryOperator.maxBy(Comparator.comparingInt(p -> p.getAge())));
long time2 = System.nanoTime();
System.out.println(o1.get() + "\nTime after stream.reduce() " + time2);
System.out.println("**** Rough execution time for stream.reduce() : " + (time2 - time1) + " nano secs");
long time3 = System.nanoTime();
System.out.println("Time before stream.max() " + time3);
Optional<Person> o2 = persons.stream().max((p01, p02) -> p01.getAge() - p02.getAge());
long time4 = System.nanoTime();
System.out.println(o2.get() + "\nTime after stream.max() " + time4);
System.out.println("**** Rough execution time for stream.max() : " + (time4 - time3) + " nano secs");
虽然这可能不是理解执行时间的理想方法,但基本上我在这里要做的是找到最早的Person
并打印出使用{{1}找出它的时间} vs stream.reduce()
。
输出
stream.max()
PS 我已多次运行此代码,更改了Time before steram.reduce()8834253431112
[ Person 9999, 9999]
Time after stream.reduce() 8834346269743
**** Rough execution time for stream.reduce() : 92838631 nano secs
Time before stream.max() 8834346687875
[ Person 9999, 9999]
Time after stream.max() 8834350117000
**** Rough execution time for stream.max() : 3429125 nano secs
和stream.max()
的顺序,发现stream.reduce()
需要更多时间才能生成输出比stream.reduce()
。
stream.max()
总是比stream.max()
快吗?如果是,那么我们应该何时使用stream.reduce()
?
答案 0 :(得分:3)
ReferencePipeline
implementation of max
如下所示:
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class MaxReducePerformance
{
public static void main(String[] args)
{
for (int n=500000; n<=5000000; n+=500000)
{
List<Person> persons = new ArrayList<>();
for (int i = 0; i < n; i++)
{
Person p = new Person();
p.setName("Person " + i);
p.setAge(i);
persons.add(p);
}
System.out.println("For " + n);
long time1 = System.nanoTime();
Optional<Person> o1 = persons.stream().reduce((p01, p02) ->
{
if (p01.getAge() < p02.getAge())
return p02;
return p01;
});
long time2 = System.nanoTime();
double d0 = (time2 - time1) / 1e9;
System.out.println("Reduce: "+d0+" seconds, " + o1);
long time3 = System.nanoTime();
Optional<Person> o2 =persons.stream().max(
(p01, p02) -> p01.getAge() - p02.getAge());
long time4 = System.nanoTime();
double d1 = (time4 - time3) / 1e9;
System.out.println("Max : "+d1+" seconds, " + o2);
}
}
}
class Person
{
String name;
int age;
void setName(String name)
{
this.name = name;
}
void setAge(int age)
{
this.age = age;
}
int getAge()
{
return age;
}
}
因此,您观察到的任何性能差异只是用于衡量性能的方法的工件。
或者,更明确地说:答案是否,它不是&#34;总是更快&#34;。
编辑:仅供参考,以下是您稍微调整过的代码版本。它会反复对不同数量的元素进行测试。 这仍然不是一个真实的,可靠的(Micro)基准测试,但比仅运行整个项目更可靠:
Error:Could not find com.android.tools.build:gradle:3.2.
Searched in the following locations:
file:/home/bunny/android-studio/gradle/m2repository/com/android/tools/build/gradle/3.2/gradle-3.2.pom
file:/home/bunny/android-studio/gradle/m2repository/com/android/tools/build/gradle/3.2/gradle-3.2.jar
https://jcenter.bintray.com/com/android/tools/build/gradle/3.2/gradle-3.2.pom
https://jcenter.bintray.com/com/android/tools/build/gradle/3.2/gradle-3.2.jar
Required by:
project :
输出应显示持续时间基本相等。
答案 1 :(得分:0)
您的reduce函数在每次迭代中评估getAge
两次,这就是为什么结果可能会慢一些,具体取决于编译器优化,重构代码并检查结果。
此外,Stream.max
可能会受益于内置的VM优化,因此您应始终坚持使用内置函数,而不是实现等效函数。