Perform multiple unrelated operations on elements of a single stream in Java

后端 未结 4 708
暗喜
暗喜 2020-12-10 17:18

How can I perform multiple unrelated operations on elements of a single stream?

Say I have a List composed from a text. Each string in the

4条回答
  •  半阙折子戏
    2020-12-10 17:42

    Here is the answer to address the OP from a different aspect. First of all, let's take a look how fast/slow to iterate a list/collection. Here is the test result on my machine by the below performance test:

    When: length of string list = 100, Thread number = 1, loops = 1000, unit = milliseconds


    OP: 0.013

    Accepted answer: 0.020

    By the counter function: 0.010


    When: length of string list = 1000_000, Thread number = 1, loops = 100, unit = milliseconds


    OP: 99.387

    Accepted answer: 89.848

    By the counter function: 59.183


    Conclusion: The percentage of performance improvement is pretty small or even slower(if the length of string list is small). generally, it's a mistake to reduce the iteration of list/collection which is loaded in memory by the more complicate collector. you won't get much performance improvements. we should look into somewhere else if there is a performance issue.

    Here is my performance test code with tool Profiler: (I'm not going to discuss how to do a performance test here. if you doubt the test result, you can do it again with any tool you believe in)

    @Test
    public void test_46539786() {
        final int strsLength = 1000_000;
        final int threadNum = 1;
        final int loops = 100;
        final int rounds = 3;
    
        final List strs = IntStream.range(0, strsLength).mapToObj(i -> i % 2 == 0 ? i + " of " + i : i + " for " + i).toList();
    
        Profiler.run(threadNum, loops, rounds, "OP", () -> {
            List wordsInStr = strs.stream().filter(t -> t.contains("of")).map(t -> t.split(" ").length).collect(Collectors.toList());
            List linePortionAfterFor = strs.stream().filter(t -> t.contains("for")).map(t -> t.substring(t.indexOf("for")))
                    .collect(Collectors.toList());
    
            assertTrue(wordsInStr.size() == linePortionAfterFor.size());
        }).printResult();
    
        Profiler.run(threadNum, loops, rounds, "Accepted answer", () -> {
            Splitter collect = strs.stream().collect(Collector.of(Splitter::new, Splitter::accept, Splitter::merge));
            assertTrue(collect.counts.size() == collect.words.size());
        }).printResult();
    
        final Function counter = s -> {
            int count = 0;
            for (int i = 0, len = s.length(); i < len; i++) {
                if (s.charAt(i) == ' ') {
                    count++;
                }
            }
            return count;
        };
    
        Profiler.run(threadNum, loops, rounds, "By the counter function", () -> {
            List wordsInStr = strs.stream().filter(t -> t.contains("of")).map(counter).collect(Collectors.toList());
            List linePortionAfterFor = strs.stream().filter(t -> t.contains("for")).map(t -> t.substring(t.indexOf("for")))
                    .collect(Collectors.toList());
    
            assertTrue(wordsInStr.size() == linePortionAfterFor.size());
        }).printResult();
    }
    

提交回复
热议问题