简体   繁体   English

为什么具有可完成未来的代码比并行流慢?

[英]why is the code with completable future slower than the parallel stream?

I am having a snippet of code.我有一段代码。 The code was for learning CompletableFuture .该代码用于学习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;
        }

    }

}

The following is the result when I ran the code.以下是我运行代码时的结果。 I can see always the execution time for the parallel stream is faster than execution time for CompletableFuture .我总是可以看到并行流的执行时间比CompletableFuture执行时间快。 I would expect the exectution time to be more or less similar.我希望执行时间或多或少相似。 Any idea why does this happens?知道为什么会发生这种情况吗?

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

I think in the second example, here:我认为在第二个例子中,这里是:

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

You wrap your code by separate Threads execution twice: once when you do parallelStream, and second time when you call CompletableFuture::join which is calling already async CompletableFuture.您通过单独的线程执行两次包装您的代码:一次是在您执行 parallelStream 时,第二次是在您调用 CompletableFuture::join 时,后者正在调用已经异步CompletableFuture。

Consider exchanging parallelStream in the second sector by stream:考虑通过流交换第二个扇区中的parallelStream:

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

PS on my machine the result after several runnings was pretty much the same: PS 在我的机器上运行几次后的结果几乎相同:

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

maybe in your case the amount of threads in common thread pool is smaller than threads needed in case #2, so changing the code like I've considered should solve the issue.也许在您的情况下,公共线程池中的线程数量小于情况#2 中所需的线程数量,因此像我考虑的那样更改代码应该可以解决问题。

The problem was with number of threads in the threadpool.问题在于线程池中的线程数。

the following code would have executed with x number of threads in a thread pool .以下代码将在线程池中使用 x 个线程执行。

shops.parallelStream().forEach(e -> System.out.println(e.getPrice()));

the following should have executed with y number of threads in the thread pool以下应该在线程池中使用 y 个线程执行

  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());

in my machine it could have been.在我的机器中它本来可以。 x > y x > y

but once i change the code below the result was different但是一旦我更改了下面的代码,结果就不同了

package com.test.omn.hello;包 com.test.omn.hello;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
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 $"));
        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 $"));
        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("sequential stream");
//      
//      long start_time = System.nanoTime();
//      long end_time = System.nanoTime();
//      double difference = (end_time - start_time) / 1e6;
//      System.out.println("execution time "+ 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();

        ExecutorService threadPool  = Executors.newFixedThreadPool(8);


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

        List<String> result1 = result.stream().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(2000l);
            } catch (InterruptedException e) {
            }
            return price;
        }

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

    }

}

Result now现在结果

parallel stream
300 $
200 $
300 $
300 $
400 $
100 $
100 $
200 $
400 $
400 $
execution time 6093.126747
completable futures stream
100 $
200 $
300 $
400 $
100 $
200 $
300 $
400 $
300 $
400 $
execution time 4022.263999

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM