【问题标题】:java 8 stream execution vs traditional loop performancejava 8 流执行与传统循环性能
【发布时间】:2017-01-07 05:43:33
【问题描述】:

我要求从属性文件中读取数据,该文件是命令分隔的,显然是字符串形式。所以在那之后我把它分成字符串数组。

我需要将该字符串数组转换为整数列表。

我尝试了两种方法:

  1. 每个循环都采用传统的铸造方式,
  2. 使用 java 8 流。

然后我想我必须根据性能计算哪个时间好。所以我有一些粗略的数据。

代码:

public class PropertyLoadCSV {
    private static Properties properties;
    public static void main(String[] args) {
        try {
            properties = new Properties();
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("resources/csvfile.properties"));

            String ids = properties.getProperty("ids");
            String[] splitedIDs = ids.split(",");

            long startTime = System.nanoTime();
            convertUsingJava7(splitedIDs);
            long endTime = System.nanoTime();
            long duration = (endTime - startTime);
            System.out.println(duration);

            long startTime1 = System.nanoTime();
            convertUsingJava8(splitedIDs);
            long endTime1 = System.nanoTime();
            long duration1 = (endTime1 - startTime1);
            System.out.println(duration1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    static List<Integer> convertUsingJava7(String[] splited){
        List<Integer> list = new ArrayList<>();
        for(String s: splited){
            list.add(Integer.valueOf(s));
        }
        return list;
    }
    static List<Integer> convertUsingJava8(String[] splited){
        return Stream.of(splited).map(Integer::parseInt).collect(Collectors.toList());
    }
}

在控制台中得到了一些意想不到的结果:

131601

254094088

Java 8 流转换和转换真的比传统方式慢吗?

我必须使用哪一个作为性能关注点?

Here's 的工作示例。

【问题讨论】:

    标签: performance java-8 java-stream


    【解决方案1】:

    你在这里测量冷启动,这是一个单一的方法调用,没有给 JIT 任何机会为你做一些好事。

    由于invokedynamic bootstrap,第一次调用lambda表达式总是很慢(它必须创建实例才能调用实际方法,但这是您只需支付一次的惩罚)。

    使用像 jmh 这样的工具来正确测量结果,无论哪种方式,您的标准代码都会比流更快,这是正常的,您必须为获得的流基础设施付出代价已创建。

    【讨论】:

    • 你好似乎很有趣。第二次迭代调用使它更快。即使是标准代码第二次运行也太快了。所以根据你的说法,如果这个功能每小时使用 20-50 次(最少通话),哪个更好?
    • 每小时 50 次? :) 你在那里测量了纳秒......选择你喜欢的任何东西,它不是性能瓶颈。
    • @user3145373:属性的加载将在一个数量级上超过其他所有内容。一旦您再次执行此操作,无论如何循环和流使用之间将没有性能差异。但附带说明一下,如果你有一个现有的数组,你应该使用Arrays.stream(array) 而不是Stream.of(varargs) 方法。而且没有理由改变语义,你仍然可以使用Integer::valueOf,就像在你的循环中一样。
    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 2015-07-25
    • 2014-03-25
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2012-08-18
    相关资源
    最近更新 更多