在使用Stream时,使用多个map()会比在单个map()中聚合所有逻辑花费更多时间吗?

时间:2018-04-26 01:10:44

标签: java functional-programming java-stream

以下是两种方法:test1()test2()

public class MoreStreams {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Brad", "Kate", "Kim", "Jack",
                "Joe", "Mike", "Susan", "George", "Robert", "Julia", "Parker", "Benson");
        test1(names);
        //test2(names);
    }

    private static void test1(List<String> names) {
        List<String> result = names.stream()
                .map(name -> sub(toUpper(toLower(name))))
                .collect(Collectors.toList());
        System.out.println(result);
    }

    private static void test2(List<String> names) {
        List<String> result = names.stream()
                .map(MoreStreams::toLower)
                .map(MoreStreams::toUpper)
                .map(MoreStreams::sub)
                .collect(Collectors.toList());
        System.out.println(result);
    }

    private static String toUpper(String name) {
        System.out.println("to Upper: " + name);
        return name.toUpperCase();
    }

    private static String toLower(String name) {
        System.out.println("to Lower: " + name);
        return name.toLowerCase();
    }

    private static String sub(String name) {
        System.out.println("to Title: " + name);
        return name.substring(1);
    }
}

第一个使用多个map(),第二个将所有逻辑聚合在一个map()中,它们是否需要相同的时间,为什么? 如果链中有更多map(),该怎么办?请帮帮我。

1 个答案:

答案 0 :(得分:0)

如果调用jit编译器没有时间进行内联和优化,那么理论上,由于额外的堆栈帧/方法调用,多重映射会更加昂贵。

但是,您测量的主要方法将需要数百万次调用,这些调用将进行jit编译并内联很多这些微观方法。他们最终可能在性能上达到平等。

这是一堆JVM args,可以显示测试过程中发生的更多事情。我会让你进行网络搜索。

-verbose:gc
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:"./gc.log"
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintCompilation
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
-XX:+UnlockDiagnosticVMOptions  -XX:+LogCompilation -XX:+PrintInlining

最后三个optins正在使用&#34; JitWatch&#34;生成一个日志文件耗材,这是一个gui程序解析和浏览所有这些东西,并以更友好的方式告诉你有关jit事件。

你应该在没有println的情况下设计你的测试。 此外,这非常重要,您应该为每个测试返回一个值,否则JIT会认为您不使用它并跳过所有代码! Microbenchmarking现在是一门科学! 见How do I write a correct micro-benchmark in Java?