1 분 소요

Java 8 이상 사용 가능한 Stream을 병렬로 사용할 수 있는 메서드. 회사에서 마이그레이션 돌릴 려고 데이터 꺼내서 살짝 가공 후 넣는 코드를 작성했는데 너무 느려서 개선해봄.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public static void main(String[] args) {  
    logger.info("vod syncronized start");  
    List<Map<String, Object>> vodList = null;  
    try {  
       vodList = SyncDAO.vodList();  
    } catch (SQLException e) {  
       logger.warn("error ", e);  
    }  
    logger.info("vod sync list size"+vodList.size());  
      
    Map<String, Object> vodInfo = new HashMap<>();  
  
       for (Map<String, Object> stringObjectMap : vodList) {  
  
           String path = stringObjectMap.get("PATH").toString();  
           if (path.startsWith("/vod/encoding/") && path.matches("/vod/encoding/\\d{4}/\\d{2}/.*")) {  
               path = path.replaceFirst("/vod", "/oldUpload");  
           }  
			  ... 
           vodInfo.put("CROP_YN", "N");  
           vodInfo.put("GIF_FILE_NAME", null);  
  
           try {  
               SyncDAO.vodInsert(vodInfo);  
           } catch (SQLException e) {  
               logger.warn("error ", e);  
           } finally {  
               logger.info("vod sync insert success");  
           }  
  
           vodInfo.put("ENCODING_FILE_NAME", stringObjectMap.get("ENCODING_FILE_NAME").toString().replace("_media1.mp4", "_thumb1.png"));  
			... 
           vodInfo.put("MEDIA_USE", "Y");  
           vodInfo.put("REG_USERID", "tgadmin");  
			...
           try {  
               SyncDAO.vodThumbInsert(vodInfo);  
           } catch (SQLException e) {  
               logger.warn("error ", e);  
           } finally {  
               logger.info("vod sync thumb insert success");  
           }  
       }  
}

대충 forEach 로 List 에 담긴 데이터 2만건을 두 테이블에 insert 하는 로직

foreEach 는 약 5분 정도 걸렸다.

이걸 parallelStream 를 사용하여 바꿔 보면 코드는

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void main(String[] args) {  
    logger.info("vod syncronized  parallelStream start");  
  
    try {  
        List<Map<String, Object>> vodList = SyncDAO.vodList();  
  
        vodList.parallelStream()  
                .forEach(SyncActionTest::insertNewDb);  
    } catch (Exception e) {  
        logger.warn("error ", e);  
    }  
  
}


private static void insertNewDb(Map<String, Object> stringObjectMap) {  
    String path = stringObjectMap.get("PATH").toString();  
    if (path.startsWith("/vod/encoding/") && path.matches("/vod/encoding/\\d{4}/\\d{2}/.*")) {  
        path = path.replaceFirst("/vod", "/oldUpload");  
    }  
    Map<String, Object> vodInfo = new HashMap<>();  
  
    logger.info("vod sync inser mediaid : " + stringObjectMap.get("MEDIA_ID"));  
    vodInfo.put("MEDIA_ID", stringObjectMap.get("MEDIA_ID"));  
    vodInfo.put("ORIGINAL_FILE_PATH", stringObjectMap.get("ORIGINAL_FILE_PATH"));  
    ... 

	SyncDAO.vodInsert(vodInfo);
}

메소드 분리 하였고

1
2
vodList.parallelStream()  
                .forEach(SyncActionTest::insertNewDb);  

다음과 같이 리스트를 parallelStream 으로 만들고 forEach 를 통해 각각 데이터에 insertNewDb 메소드를 실행해 줬다.

이 결과

약 1분 30초로 대폭 빨라졌다.

물론 parallelStream 는 병렬 처리를 하기 때문에 순서나, 여러 쓰레드에서 접근 가능한 변수 등이 중요하면 사용할 때 고민해봐야 할 것 같다.

참고 : 그냥 Stream은 5분 걸렸다.

태그: ,

카테고리:

업데이트:

댓글남기기