public void saveTradeList() {
List<Stock> stocks = stockRepository.findAll();
List<TradeDto> trades = jsoupCrawling.getTrades(stocks);
User user = userRepository.findById(1L).orElseThrow(()->
new IllegalArgumentException("id가 1인 유저가 존재하지 않습니다."));
long start = System.currentTimeMillis();
List<Buy> buys = trades.stream().map((tradeDto -> new Buy(tradeDto.getQuantity(), tradeDto.getPrice(), tradeDto.getStock(), user))).toList();
List<Sell> sells = trades.stream().map((tradeDto -> new Sell(tradeDto.getQuantity(), tradeDto.getPrice(), tradeDto.getStock(), user))).toList();
buyRepository.saveAll(buys);
sellRepository.saveAll(sells);
long end = System.currentTimeMillis();
System.out.println("걸린 시간 : " + (end - start));
}
다음과 같이 크롤링을 통해 얻어온 거래 내역 데이터를 Buy, Sell엔티티로 변환하여 DB에 저장하는 메소드가 있다.
저장하는 데이터의 갯수가 종목당 400개이고 2000종목이라 많게는 80만건의 거래내역을 두곳의 repository에 저장하므로 오랜시간이 걸릴것 같았다.
이를 개선하기 위해 parallelStream을 고안하여 도입하였다.
개발자가 직접 쓰레드를 생성하거나 관리할 필요없이 parallelStream()이나 parallel()을 사용하면 알아서ForkJoinFramework를 사용하여 작업을 분할하여 병렬적으로 처리하게 된다.
다음과 같이 스트림을 재귀적으로 분할하고 각 서브 스트림을 서로 다른 스레드의 리듀싱 연산으로 할당하고 결과를 하나의 값으로 합쳐야한다.
하지만 실행 순서는 우리가 통제할 수 없기 때문에 실행 순서가 결과에 영향을 주지 않고 한 요소의 상태가 다른 요소애 영향을 주지 않고 소스 데이터도 영향을 받지 않는 경우 병렬 스트림을 사용하는것이 좋다.
또한 자료구조 마다 효율이 다르다는 특징이 있다.
예를 들어 LinkedList는 분할하기 위해서 모든 요소를 탐색해야하지만 ArrayList는 탐색하지 않아도 분할이 가능하다.때문에 LinkedList를 parallelStream을 사용하여 처리하게 되면 나쁜 효율을 보인다.
나의 코드는 ArrayList자료구조의 데이터를 다루기 떄문에 parallelStream을 사용했을 때 더 빠른것을 확인할 수 있다.
stream()사용
parallelStream() 사용
'언어 > JAVA' 카테고리의 다른 글
[TIL]20230722 - 빌더 패턴 (0) | 2023.07.24 |
---|---|
[TIL]20230622 - 예외처리 (0) | 2023.06.22 |
[TIL]20230620 - 상속과 다형성 (0) | 2023.06.21 |
[TIL]20230615 - 스트림의 toList()가 없다 (2) | 2023.06.16 |
[TIL]20230613 - HashSet 의 저장방법 (0) | 2023.06.14 |