Java8 Lambda性能与公共功能
我已经使用
Java8 VS对lambda性能进行了一些演示测试. Java8公共功能.
案例如下: >我有一个10人(5男5女)的名单. 现在,当我执行这些步骤数百万次时,结果将是:
现在我没想到lambda的执行时间比普通函数长两倍到六倍. 所以,现在我非常想知道我是否错过了这里的一些东西. 源代码可以在这里找到:pastebin.com/BJBk4Tu6 跟进: >将列表扩展为1.000.000项时 结果将是:
但是,当我尝试过滤100,000次现有的1.000.000人时,结果将是:
因此,作为最终结论:Lambdas在过滤较大列表时更快,而公共函数(旧方法)在过滤较小列表时更快. 此外,在过滤任何列表时,公共功能更快,无论出于何种目的,您都需要这样做. 最新代码:pastebin.com/LcVhgnYv 解决方法
正如评论中所指出的那样:你很难从这样一个简单而孤立的微基准测试中得出任何结论.
从another (otherwise unrelated) answer部分引用:
我将这些基本步骤应用到您的程序中.这是MCVE:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.Collectors; class Person { public static final int MALE = 0; public static final int FEMALE = 1; private final String name; private final int sex; private final int age; public Person(String name,int sex,int age) { this.name = name; this.sex = sex; this.age = age; } public int getSex() { return sex; } public int getAge() { return age; } } public class Main { public static void main(String[] args) { new Main(); } private List<Person> people; public Main() { for (int size=10; size<=1000000; size*=10) { Random r = new Random(0); people = new ArrayList<Person>(); for (int i = 0; i < size; i++) { int s = r.nextInt(2); int a = 25 + r.nextInt(20); people.add(new Person("p" + i,s,a)); } int min = 10000000 / size; int max = 10 * min; for (int n = min; n <= max; n += min) { lambdaMethodUsingForEach(n); lambdaMethodUsingCollect(n); defaultMethod(n); } } } public void lambdaMethodUsingForEach(int n) { List<Person> lambdaOutput = new ArrayList<Person>(); long lambdaStart = System.currentTimeMillis(); for (int i = 0; i < n; i++) { lambdaOutput.addAll(getFemaleYoungAdultsUsingLambdaUsingForEach()); } System.out.printf("List size: %10d,runs: %10d,result: %10d,ForEach took: " + (System.currentTimeMillis() - lambdaStart) + " msn",people.size(),n,lambdaOutput.size()); } public void lambdaMethodUsingCollect(int n) { List<Person> lambdaOutput = new ArrayList<Person>(); long lambdaStart = System.currentTimeMillis(); for (int i = 0; i < n; i++) { lambdaOutput.addAll(getFemaleYoungAdultsUsingLambdaUsingCollect()); } System.out.printf("List size: %10d,collect took: " + (System.currentTimeMillis() - lambdaStart) + " msn",lambdaOutput.size()); } public void defaultMethod(int n) { List<Person> defaultOutput = new ArrayList<Person>(); long defaultStart = System.currentTimeMillis(); for (int i = 0; i < n; i++) { defaultOutput.addAll(getFemaleYoungAdultsUsingFunctions()); } System.out.printf("List size: %10d,default took: " + (System.currentTimeMillis() - defaultStart) + " msn",defaultOutput.size()); } public List<Person> getFemaleYoungAdultsUsingLambdaUsingForEach() { List<Person> people = new ArrayList<Person>(); this.people.stream().filter( (p) -> p.getSex() == Person.FEMALE && p.getAge() >= 18 && p.getAge() <= 25).forEach(people::add); return people; } public List<Person> getFemaleYoungAdultsUsingLambdaUsingCollect() { return this.people.stream().filter( (p) -> p.getSex() == Person.FEMALE && p.getAge() >= 18 && p.getAge() <= 25).collect(Collectors.toList()); } public List<Person> getFemaleYoungAdultsUsingFunctions() { List<Person> people = new ArrayList<Person>(); for (Person p : this.people) { if (p.getSex() == Person.FEMALE && p.getAge() >= 18 && p.getAge() <= 25) { people.add(p); } } return people; } } MyMachine?上的输出与此类似: ... List size: 10,runs: 10000000,result: 10000000,ForEach took: 1482 ms List size: 10,collect took: 2014 ms List size: 10,default took: 1013 ms ... List size: 100,runs: 1000000,result: 3000000,ForEach took: 664 ms List size: 100,collect took: 515 ms List size: 100,default took: 441 ms ... List size: 1000,runs: 100000,result: 2300000,ForEach took: 778 ms List size: 1000,collect took: 721 ms List size: 1000,default took: 841 ms ... List size: 10000,runs: 10000,result: 2450000,ForEach took: 970 ms List size: 10000,collect took: 971 ms List size: 10000,default took: 1119 ms ... List size: 100000,runs: 1000,result: 2536000,ForEach took: 976 ms List size: 100000,collect took: 1057 ms List size: 100000,default took: 1109 ms ... List size: 1000000,runs: 100,result: 2488600,ForEach took: 1323 ms List size: 1000000,collect took: 1305 ms List size: 1000000,default took: 1422 ms 您可以看到ForEach和默认(公共方法)方法之间的差异即使对于较小的列表也会消失.对于较大的列表,基于lambda的方法甚至似乎有一点点优势. 再次强调这一点:这是一个非常简单的微基准测试,即使这并不一定能说明这些方法在实践中的表现.但是,至少可以合理地假设ForEach和公共方法之间的差异不如初始测试所建议的那么大. Nevertleless:对于任何在JMH或Caliper中运行此操作的人来说,我都有1个,并对此发表了一些进一步的见解. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |