java中Stream API中“filter()”方法的性能[重复]
Posted
技术标签:
【中文标题】java中Stream API中“filter()”方法的性能[重复]【英文标题】:Performance of "filter()" method in Stream API in java [duplicate] 【发布时间】:2021-05-22 18:55:27 【问题描述】:我想知道java的流API处理这两种情况的方式是相同的还是不同的?如果它要为每个过滤器执行一个独立的循环,那么我认为在性能方面存在显着差异。你觉得怎么样?
这是两个条件
1. filter(cond1 && cond2 && cond3)
2. filter(cond1).filter(cond2).filter(cond3)
例子
List<Employee> emps1 = employees.stream()
.filter((Employee e) -> e.name.endsWith("n") && e.salary > 10000 && e.id % 2 == 1)
.collect(Collectors.toList());
List<Employee> emps2 = employees.stream()
.filter(e -> e.name.endsWith("n"))
.filter(e -> e.salary > 10000)
.filter(e -> e.id % 2 == 1)
.collect(Collectors.toList());
【问题讨论】:
读取选项,第一个将与“ands”连接的条件应用于整个数据,其他将 cond1 应用于整个数据,其他每个应用于缩减集。我对你的建议是用你拥有的数据来衡量自己——我想即使你交换条件顺序,它们也会出现差异。 TLDR:编译器处理它的方式不同。我们可以参考这个***.com/a/48513110/1285923。他们在字节码级别对编译器如何处理它进行了分析。性能方面,IMO 不会有太大差别,唯一的优化是在算子短路上。 在更容易阅读的地方编写代码,第二个似乎是这样做的方式。性能方面,几乎没有差异 任何性能问题只有通过基准测试才能真正得到回答。假设只能到此为止。我建议你对代码进行基准测试并找出答案。 【参考方案1】:在filter(cond1 && cond2 && cond3)
的情况下,只要任何条件评估为false
,条件处理就会停止,例如如果cond1
的计算结果为false
,则不会处理其他条件(cond2
和cond3
)。同样,如果 cond1
计算为 true
,则处理将继续计算 cond2
,如果计算结果为 false
,则不会计算条件 cond3
。
filter(cond1).filter(cond2).filter(cond3)
的处理方式也是一样的,从下面的例子可以看出:
import java.util.stream.Stream;
public class Main
public static void main(String[] args)
Stream.of("one", "two", "three", "four")
.filter(s ->
System.out.println("Hello");
return s.contains("t");
)
.filter(s ->
System.out.println("Hi");
return s.contains("f");
)
.forEach(System.out::println);
输出:
Hello
Hello
Hi
Hello
Hi
Hello
因此,它没有任何区别,这是一个选择问题。第二个看起来更干净。
注意:对于更复杂的表达式,您可以使用Predicate#and
,它还有两个好处:
-
您可以在代码中将
Predicate
实现的行为与其他流重用。
更简洁的代码。
演示:
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Main
public static void main(String[] args)
Predicate<String> containsT = s -> s.contains("t");
Predicate<String> containsE = s -> s.contains("e");
Stream.of("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")
.filter(containsT.and(containsE))
.forEach(System.out::println);
输出:
three
eight
ten
但是,它对处理的方式没有任何影响。
【讨论】:
"在 filter(cond1).filter(cond2).filter(cond3) 的情况下,所有的条件都会被评估。 - 有来源吗?我不相信这是普遍正确的,如果有的话。 我知道流处理是如何工作的,但是所有过滤器都针对每个元素执行的想法是错误的;如果他们没有通过第一个过滤器,则不会评估连续的过滤器。 ideone.com/yjOS8u以上是关于java中Stream API中“filter()”方法的性能[重复]的主要内容,如果未能解决你的问题,请参考以下文章