java - 为什么具有可完成 future 的代码比并行流慢?

标签 java java-8 java-stream completable-future

我有一段代码。该代码用于学习CompletableFuture

package com.test.omn.hello;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class CompletableFutureLearning {

    public static void main(String[] args) {

        List<Shop> shops = new ArrayList<>();

        shops.add(new Shop("Videocon Tv", "100 $"));
        shops.add(new Shop("Videocon Tv", "200 $"));
        shops.add(new Shop("Videocon Tv", "300 $"));
        shops.add(new Shop("Videocon Tv", "400 $"));
        long start_time;
        long end_time;
        double difference;


        System.out.println("parallel stream");
        start_time = System.nanoTime();
        shops.parallelStream().forEach(e -> System.out.println(e.getPrice()));
        end_time = System.nanoTime();
        difference = (end_time - start_time) / 1e6;
        System.out.println("execution time " + difference);

        System.out.println("completable futures stream");
        start_time = System.nanoTime();

        List<CompletableFuture<String>> result = shops.parallelStream()
                .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice())).collect(Collectors.toList());

        List<String> result1 = result.parallelStream().map(CompletableFuture::join).collect(Collectors.toList());

        result1.forEach(e -> System.out.println(e));
        end_time = System.nanoTime();
        difference = (end_time - start_time) / 1e6;
        System.out.println("execution time " + difference);

    }

    static public class Shop {

        public Shop(String name, String price) {
            super();
            this.name = name;
            this.price = price;
        }

        private String name;

        private String price;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPrice() {

            try {
                Thread.sleep(3000l);
            } catch (InterruptedException e) {
            }
            return price;
        }

        public void setPrice(String price) {
            this.price = price;
        }

    }

}

以下是我运行代码时的结果。我可以看到并行流的执行时间总是比 CompletableFuture 的执行时间快。我希望执行时间或多或少相似。知道为什么会发生这种情况吗?

parallel stream
300 $
400 $
100 $
200 $
execution time 3079.88547
completable futures stream
100 $
200 $
300 $
400 $
execution time 6018.84133

最佳答案

我认为在第二个例子中,这里:

List<String> result1 = result.parallelStream().map(CompletableFuture::join).collect(Collectors.toList());

您通过单独的线程执行两次包装代码:一次是在执行parallelStream时,第二次是在调用CompletableFuture::join(正在调用已经异步 CompletableFuture)时。

考虑按流交换第二个扇区中的parallelStream:

List<String> result1 = result.stream().map(CompletableFuture::join).collect(Collectors.toList());

附注在我的机器上,多次运行后的结果几乎相同:

parallel stream
300 $
400 $
200 $
100 $
execution time 3007.854272
completable futures stream
100 $
200 $
300 $
400 $
execution time 3006.914028

也许在您的情况下,公共(public)线程池中的线程数量小于情况 #2 所需的线程数量,因此像我考虑的那样更改代码应该可以解决问题。

关于java - 为什么具有可完成 future 的代码比并行流慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59345824/

相关文章:

java - Oracle 如何在从 plsql 调用 java 时导入缺少的 java 类

java - bukkit - 防止玩家在战斗中运行命令

java - 以编程方式失败的 Maven 测试 JUnit5 测试

java - 扩展现有的流收集器实例

java - 函数式编程如何变得更好 (Java 8)

java - Travis Spring 的 JUnit 测试失败

java - 将列表值流式传输到 Map.Entry.values

java - 创建一个自定义的类 IntStream 类

java - 如果列表不为空,如何使用我的服务使用 Java 8 lambda/streams 删除列表中的每个元素

java - 使用 Java8 流重写