Java 8 Stream单个filter与多个filter性能对比

有一天,看在同事在用filter(...).filter(...).filter(...),当时很震惊,为何会如些写,而且说这样写性能很高,根据我多年的经验来说,此事并非如些,于是就做了本期测试:测试如下:

测试数据 10 万条:

Single==1 == 5
Multi==1 == 21
Single==2 == 2
Multi==2 == 5
Single==3 == 2
Multi==3 == 2
Single==4 == 2
Multi==4 == 3
Single==5 == 2
Multi==5 == 3
Single==6 == 2
Multi==6 == 4
Single==7 == 17
Multi==7 == 2
Single==8 == 2
Multi==8 == 2
Single==9 == 2
Multi==9 == 4
Single==10 == 2
Multi==10 == 2
Single==11 == 2
Multi==11 == 3
Single==12 == 2
Multi==12 == 5
Single==13 == 2
Multi==13 == 1
Single==14 == 2
Multi==14 == 2
Single==15 == 1
Multi==15 == 2
Single==16 == 2
Multi==16 == 2
Single==17 == 2
Multi==17 == 1
Single==18 == 2
Multi==18 == 2
Single==19 == 1
Multi==19 == 2
Single==20 == 1
Multi==20 == 2

测试数据 100 万条:

Single==1 == 16
Multi==1 == 20
Single==2 == 10
Multi==2 == 13
Single==3 == 11
Multi==3 == 14
Single==4 == 12
Multi==4 == 12
Single==5 == 11
Multi==5 == 12
Single==6 == 11
Multi==6 == 13
Single==7 == 11
Multi==7 == 12
Single==8 == 12
Multi==8 == 12
Single==9 == 11
Multi==9 == 12
Single==10 == 11
Multi==10 == 12
Single==11 == 11
Multi==11 == 12
Single==12 == 11
Multi==12 == 15
Single==13 == 11
Multi==13 == 12
Single==14 == 11
Multi==14 == 12
Single==15 == 11
Multi==15 == 14
Single==16 == 11
Multi==16 == 13
Single==17 == 11
Multi==17 == 16
Single==18 == 12
Multi==18 == 14
Single==19 == 12
Multi==19 == 14
Single==20 == 14
Multi==20 == 12

测试数据 1000 万条:

Single==1 == 94
Multi==1 == 138
Single==2 == 105
Multi==2 == 167
Single==3 == 124
Multi==3 == 155
Single==4 == 126
Multi==4 == 145
Single==5 == 116
Multi==5 == 145
Single==6 == 119
Multi==6 == 148
Single==7 == 117
Multi==7 == 147
Single==8 == 118
Multi==8 == 146
Single==9 == 117
Multi==9 == 146
Single==10 == 117
Multi==10 == 146
Single==11 == 117
Multi==11 == 148
Single==12 == 117
Multi==12 == 146
Single==13 == 117
Multi==13 == 146
Single==14 == 117
Multi==14 == 146
Single==15 == 117
Multi==15 == 159
Single==16 == 117
Multi==16 == 147
Single==17 == 116
Multi==17 == 146
Single==18 == 116
Multi==18 == 146
Single==19 == 120
Multi==19 == 145
Single==20 == 116
Multi==20 == 147

测试数据 2000 万条

Single==1 == 191
Multi==1 == 288
Single==2 == 224
Multi==2 == 303
Single==3 == 253
Multi==3 == 298
Single==4 == 240
Multi==4 == 301
Single==5 == 236
Multi==5 == 298
Single==6 == 234
Multi==6 == 299
Single==7 == 234
Multi==7 == 298
Single==8 == 235
Multi==8 == 300
Single==9 == 233
Multi==9 == 297
Single==10 == 236
Multi==10 == 297
Single==11 == 237
Multi==11 == 298
Single==12 == 236
Multi==12 == 301
Single==13 == 236
Multi==13 == 297
Single==14 == 237
Multi==14 == 302
Single==15 == 236
Multi==15 == 300
Single==16 == 240
Multi==16 == 310
Single==17 == 234
Multi==17 == 298
Single==18 == 235
Multi==18 == 296
Single==19 == 232
Multi==19 == 301
Single==20 == 234
Multi==20 == 298

测试代码如下,可自行测试:


import lombok.Data;
import org.junit.Test;
import org.springframework.util.StopWatch;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {

    @Data
    public static class TestDTO {
        private Integer id;
        private String na;
    }

    @Test
    public void test(){
        StopWatch watch = new StopWatch();
        int total = 20000000;
        TestDTO[] arr = new TestDTO[total];
        int i = 0;
        while (i++ < total) {
            TestDTO source = new TestDTO();
            source.setId(i);
            source.setNa("a" + i);
            arr[i-1] = source;
        }
        List<TestDTO> list = Stream.of(arr).collect(Collectors.toList());
        int k = 0;
        while (k++ < 20) {
            watch.start("Single==" + k);
            List<TestDTO> collect2 = list.stream().filter(
                t -> t.getId() % 3 == 0
                    && t.getId() % 2 == 0
                    && t.getId() % 5 == 0
                    && t.getNa().endsWith("70")).collect(Collectors.toList());
            watch.stop();
            watch.start("Multi==" + k);
            List<TestDTO> collect = list.stream()
                .filter(t -> t.getId() % 3 == 0)
                .filter(t -> t.getId() % 2 == 0)
                .filter(t -> t.getId() % 5 == 0)
                .filter(t -> t.getNa().endsWith("70"))
                .collect(Collectors.toList());
            watch.stop();
        }
        Stream.of(watch.getTaskInfo()).forEach(
            ti -> System.out.println(ti.getTaskName() + " == " + ti.getTimeMillis()));
    }
}

原因如下:假定数据为1000万条,单个filter只需要扫描1000万次,多个filter扫描1000万+第一个filter的结果数+第二个filter的结果数+...,依此类推。

基于些理论,代码改动如下:

@Test
    public void test(){
        StopWatch watch = new StopWatch();
        int total = 10000000;
        TestDTO[] arr = new TestDTO[total];
        int i = 0;
        while (i++ < total) {
            TestDTO source = new TestDTO();
            source.setId(i);
            source.setNa("a" + i);
            arr[i-1] = source;
        }
        List<TestDTO> list = Stream.of(arr).collect(Collectors.toList());
        int k = 0;
        while (k++ < 20) {
            watch.start("Single==" + k);
            List<TestDTO> collect2 = list.stream().filter(
                t -> t.getId() % 1 == 0
                    && t.getId() % 1 == 0
                    && t.getId() % 2 == 0
                    && t.getId() % 5 == 0
                    && t.getNa().endsWith("70")).collect(Collectors.toList());
            watch.stop();
            watch.start("Multi==" + k);
            List<TestDTO> collect = list.stream()
                .filter(t -> t.getId() % 1 == 0)
                .filter(t -> t.getId() % 1 == 0)
                .filter(t -> t.getId() % 2 == 0)
                .filter(t -> t.getId() % 5 == 0)
                .filter(t -> t.getNa().endsWith("70"))
                .collect(Collectors.toList());
            watch.stop();
        }
        Stream.of(watch.getTaskInfo()).forEach(
            ti -> System.out.println(ti.getTaskName() + " == " + ti.getTimeMillis()));
    }

测试结果:

Single==1 == 94
Multi==1 == 222
Single==2 == 110
Multi==2 == 234
Single==3 == 128
Multi==3 == 226
Single==4 == 116
Multi==4 == 236
Single==5 == 120
Multi==5 == 229
Single==6 == 120
Multi==6 == 237
Single==7 == 124
Multi==7 == 235
Single==8 == 118
Multi==8 == 236
Single==9 == 117
Multi==9 == 234
Single==10 == 116
Multi==10 == 228
Single==11 == 123
Multi==11 == 235
Single==12 == 117
Multi==12 == 227
Single==13 == 117
Multi==13 == 224
Single==14 == 115
Multi==14 == 232
Single==15 == 116
Multi==15 == 229
Single==16 == 116
Multi==16 == 232
Single==17 == 122
Multi==17 == 245
Single==18 == 121
Multi==18 == 235
Single==19 == 117
Multi==19 == 226
Single==20 == 116
Multi==20 == 231

总结:单个filter比多个filter性能更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值