ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 분석기 성능 튜닝(정규식)
    elasticsearch 2021. 12. 5. 16:42
    반응형

    개요

    이번에 무신사에서는 블랙프라이데이를 진행하였고 그에 맞춰 상품 관련 노드를 20대를 사용해서 트래픽을 받을 준비를 하였다

    그러나 그럼에도 로드가 많이 튀고 cpu 사용량도 엄청 튀는 것이었다 그래서 전체 분석기를 튜닝하지는 못해도 커스텀 분석기 중 튜닝할 만한 게 있나 체크를 하였다

     

    분석

    사실 분석이라고 말은 거창하게 했지만 전부터 고치려고 했었던 것이 있었는데 얼마나 좋아지겠어?라고 생각하고 고치지 않았던 것이 있었는데 그것부터 고치려고 했었다 보통 웹에서는 정규식을 사용해 validation을 하거나 string.matches를 많이 사용한다  그 이유는 input 값에 대해 각각 문자를 validation 하기보다는 전체 값을 validation 하기 때문이다

     

    예를들면 모바일만 서비스하는 곳은 필요 없을 수도 있지만 pc에서 검색할 때는 "tkatjdwjswk 태블릿"과 같이 검색하는 문자를 "삼성전자 태블릿"으로 변경해주기 위해서 영한 오타의 경우에는 "t", "k", "a"...."릿"까지 각 문자가 영문인지 확인하고 그 영문을 조합 조합하는 작업을 하게 되기 때문이다

     

    변경

    실제 코드는 아니지만 흐름은 아래 코드와 같다

    //전
    String regex = "[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]";
    
    long start = System.currentTimeMillis();
    for (int i = 0; i < 50000000; i++) {
    	"하하호호".matches(regex);
    }
    long end = System.currentTimeMillis();
    System.out.println((end - start) / 1000);
    
    //후
    Pattern pattern = Pattern.compile(regex);
    final Matcher matcher = pattern.matcher("");
    
    start = System.currentTimeMillis();
    for (int i = 0; i < 50000000; i++) {
    	matcher.reset("하하호호");
    	matcher.matches();
    }
    
    end = System.currentTimeMillis();
    System.out.println((end - start) / 1000);

     

     

    전에 사용하던 코드와 변경후의 코드이다 반복문에서 매번 matches 하던 코드를 반복문 밖에 미리 컴파일하고 그것을 재사용하는 코드로 변경해주었다

    String.matches 코드 내부를 보게 되면 아래처럼 되어있는데 결국 매번 compile을 하고 있는 것이다

    //String matches
    public static boolean matches(String regex, CharSequence input) {
    	Pattern p = Pattern.compile(regex);
    	Matcher m = p.matcher(input);
    	return m.matches();
    }
    
    //Patteren matches
    public static boolean matches(String regex, CharSequence input) {
    	Pattern p = Pattern.compile(regex);
    	Matcher m = p.matcher(input);
    	return m.matches();
    }

     

    결과

    코드를 테스트 해보면 500만 번 기준으로 속도 차이가 나의 pc에선 느 8배 정도 차이가 나며 실제 코드에서는 2~3배까지 차이가 났다

    누가 보면 당연한거 아니야? 하겠지만 나는 당연히 차이가 나겠다고 생각은 했지만 이렇게 성능 차이가 날지는 몰랐다

    정말 별거라고 생각하지 않았던 게 많은 비용을 지출했던 것이다

     

    compile 하는데 비용이 굉장히 많이 지출되는데 내부 데이터 구조로 컴파일 되게 되는데 그것을 매번 하게 되니 많이 비용이 지출된 것이다

    자세하게 알아보고 싶다면 아래 링크를 클릭해서 확인해보면 좋을 것 같다

    https://www.baeldung.com/java-regex-performance

     

    편안한 게 좋기는 하지만 대가를 치르는 것도 분명히 많기 때문에 일일이 다 확인은 하지 못하더라도 내부가 어떻게 실행되는지 확인할 필요는 있을 것 같다

    반응형

    댓글

Designed by Tistory.