블로그 이미지

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • String.matches() VS Pattern.compile()
    Programming/Java 2022. 2. 18. 02:03

    문제 상황

    정규표현식을 사용하여 문자열을 검증할 때, 가장 간단한 방법은 String.matches()를 사용하는 것이다. 다음은 입력 받은 문자열이 숫자만으로 이루어져있는지 검증하는 코드이다.

    private static boolean isNumber(String line) {
        return line.matches("^[0-9]+$");
    }

    그런데, 이 방법은 여러번 반복해서 해당 코드가 실행될 경우 성능 상 이슈가 있다! Pattern 클래스는 객체 생성에 대한 비용이 비싼데, String.matches() 를 사용할 때 마다 Pattern 클래스의 인스턴스를 생성하기 때문이다.

    public boolean matches(String regex) {
        return Pattern.matches(regex, this);
    }

    위 코드는 String 클래스의 matches 메서드의 구현이다. Pattern.matches를 호출하여 반환하는 것으로 보인다. 다시 Pattern클래스의 matches 구현체로 들어가보면 아래와 같다.

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

    이 Pattern 클래스의 matches 메서드에서 생성 비용이 비싸다는 Pattern 클래스의 인스턴스를 생성하고 있다. String.matches() 를 사용할 때 마다 Pattern 객체가 생성되고, 사용이 끝나면 GC 대상이 되어 버려지게 되기 때문에 여러번 반복할 경우 성능이 안좋아 지는 것이다!

    해결 방법

    그렇다면, 이 문제를 어떻게 해결할까? 바로, Pattern 객체를 캐싱해두어 재사용하는 것이다

    public class InputView{
        private static final Pattern NUMBER = Pattern.compile("^[0-9]+$");
    
        private static boolean isNumber(String line) {
            return !NUMBER.matcher(line).matches();
        }
    }

    위와 같이 Pattern 객체를 캐싱해두면 숫자 검증 로직이 여러번 실행되어도 Pattern 객체가 재생성 되지 않기 때문에 성능 관점에서의 이슈가 줄어들게 된다. 물론, 메서드를 한번도 호출하지 않는다면 불필요한 생성이 된 것이지만, 여러번 생성했을 때의 성능 이슈와 비교한다면 그 정도의 trade-off 는 감수할 만 하다고 생각된다.

    참고자료

    Effective Java 3/E 2장 Item 6 : 불필요한 객체 생성을 피하라

    'Programming > Java' 카테고리의 다른 글

    불변 객체는 어떻게 만드는가?  (4) 2022.03.04

    댓글

Designed by Tistory.