-
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