Avatar
0
Nguyễn Thái Sơn Professional
Nguyễn Thái Sơn Professional
Khi nào nên thật sự dùng Stream
em hồi trước có hỏi anh về for loop và stream và công nhận stream thì tiện lợi nhưng chậm hơn for loop, như vậy 1 lượng data lớn coi như for loop hơn hẳn về performance. Vậy em cũng chưa thật sự hiểu case nào nên dùng stream, ngoài sự tiện lợi của nó ra em thấy nó thua hẳn for loop về tốc độ

Theo như a test lần trước thì nó hơn hẳn 2.5 lần stream luôn : https://stackask.com/question/co-nen-dung-stream-thay-cho-for-loop/ (16 so với 41)

  • Answer
Remain: 5
1 Answer
Avatar
Thành Lê Văn Professional
Thành Lê Văn Professional
Hmm, khi bạn muốn tạo một pipe logic thì hãy sử dụng stream.

Nếu chỉ nói về tốc độ mà không nói đến lợi ích của các operations thì thông thường Stream sẽ chậm hơn, nếu nhanh hơn thì sẽ cần tốn tài nguyên của CPU.

Stream chậm hơn bởi vì java cần phân tích các operations, thực hiện nhiều câu lệnh logic để chuẩn bị cho stream. (Cơ mà k chậm đến lỗi kém hơn 2.5 lần đâu, check lại test case)

Tuy nhiên nếu dùng stream parallel thì tốc độ sẽ rất nhanh ==> cần tài nguyên CPU, khi đó các task không cần chờ tập hợp tất cả data sẽ được chạy song song trên nhiều thread.

Ví dụ bạn có 200 data là int.

Mỗi data đó bạn cần thực hiện các task sau:

Task 1: Nhân các số với 2 : Mỗi lần thực hiện mất 10ms
Task 2: Chia các số với 3 : Mỗi lần thực hiện mất 20ms
Task 3: Nhân các số với 5 : Mỗi lần thực hiện mất 10ms
Task 4: Cộng các số thêm 5 : Mỗi lần thực hiện mất 20ms
public class Main {

  public static void main(String[] args) {
    // Task 1: Nhân các số với 2 : Mỗi lần thực hiện mất 10ms
    // Task 2: Chia các số với 3 : Mỗi lần thực hiện mất 20ms
    // Task 3: Nhân các số với 5 : Mỗi lần thực hiện mất 10ms
    // Task 4: Cộng các số thêm 5 : Mỗi lần thực hiện mất 20ms

    final List<Integer> listOrigin = new ArrayList();
    for (int i = 0; i < 200; ++i) {
      listOrigin.add(i);
    }

    forLoop(listOrigin);

    stream(listOrigin);
  }

  private static void stream(List<Integer> listOrigin) {
    final long streamStartTime = System.currentTimeMillis();
    listOrigin.stream().parallel().map(data -> {
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return new TempDto(data, data * 2);
    }).map(data -> {
      try {
        Thread.sleep(20);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return new TempDto(data.origin, data.result / 3);
    }).map(data -> {
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return new TempDto(data.origin, data.result * 5);
    }).map(data -> {
      try {
        Thread.sleep(20);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return new TempDto(data.origin, data.result + 5);
    }).collect(Collectors.toList());
    final long streamElapsed = System.currentTimeMillis() - streamStartTime;
    System.out.println("stream elapsed: " + streamElapsed);
  }
  public static class TempDto {

    Integer origin;
    Integer result;

    public TempDto(Integer origin, Integer result) {
      this.origin = origin;
      this.result = result;
    }
  }

  private static void forLoop(List<Integer> listOrigin) {
    try {
      final Map<Integer, Integer> forLoopCopy = new HashMap<>();
      final long forLoopStartTime = System.currentTimeMillis();
      for (Integer item : listOrigin) {
        Thread.sleep(10);
        int resultTask1 = item * 2;
        
        Thread.sleep(20);
        int resultTask2 = resultTask1 / 3;
        
        Thread.sleep(10);
        int resultTask3 = resultTask2 * 5;
        
        Thread.sleep(20);
        int resultTask4 = resultTask3 + 5;
        forLoopCopy.put(item, resultTask4);
      }
      final long forLoopElapsed = System.currentTimeMillis() - forLoopStartTime;
      System.out.println("for loop elapsed: " + forLoopElapsed);
    } catch (Exception exception) {
      exception.printStackTrace();
    }
  }

}

Kết quả ở máy mình chạy sẽ là :

for loop elapsed: 18725
stream elapsed: 2521

Còn nhiều lý do nữa nhưng 12h đêm rùi, mình ngủ đây :D

  • 0
  • Reply
e cảm ơn, anh có thời gian chia sẻ em tiếp nhé bài viết hay quá  –  Nguyễn Thái Sơn 1656397405000
Có câu hỏi, rảnh rảnh tui sẽ vào trả lời.  –  Thành Lê Văn 1656487667000