首页 > 解决方案 > Stream中“先过滤后映射”和“先映射后过滤”的性能是否不同?

问题描述

我想知道什么更快:按字段过滤自定义对象,然后按其字段映射,反之亦然(映射然后过滤)。
最后,我通常想将映射的字段收集到一些集合中。

例如最简单的 Person 类:

public class Person {
    String uuid;
    String name;
    String secondName;
}

现在让我们有一个List<Person> persons.

List<String> filtered1 = persons
                .stream()
                .filter(p -> "NEED_TOY".equals(p.getName()))
                .map(Person::getName)
                .collect(Collectors.toList());
// or?
List<String> filtered2 = persons
                .stream()
                .map(Person::getName)
                .filter(p -> "NEED_TOY".equals(p))
                .collect(Collectors.toList());

标签: javajava-8java-stream

解决方案


在这个具体的例子中,调用Person.getName()基本上没有成本,没关系,你应该使用你认为最易读的东西(并且过滤之后甚至可以稍微快一点,因为正如 TJ 提到的那样,映射操作是一部分的过滤操作)。

但是,如果映射操作的成本很高,那么首先过滤(如果可能)会更有效,因为流不必映射已过滤掉的元素。

让我们举一个人为的例子:你有一个 ID 流,对于流中的每个偶数 ID,你必须执行一个 http GET 请求或一个数据库查询来获取由这个 ID 标识的项目的详细信息(从而映射ID 到详细对象)。

假设流由一半偶数和一半奇数组成,并且每个请求花费相同的时间,您可以通过先过滤将时间除以 2。如果每个 http 请求需要 1 秒,并且您有 60 个 ID,那么通过先过滤,您可以将同一任务从 60 秒缩短到 30 秒,并且还可以减少网络和外部 http API 的费用。


推荐阅读