1주차 리뷰를 달던 중 아래와 같은 코멘트를 발견했다.
String.matches가 성능 이슈가 있다고?
정규식 비교는 앞으로도 계속 쓸텐데... 이 부분에 대해 알아봐야겠다는 생각이 들었다!
나도 따로 Pattern 객체 없이 String.matches를 사용하는 편이었는데, 한 쪽에서는 궁금증이 있었왔다.
'Pattern 객체로 compile해 사용하면 더 코드가 늘어나는데
같은 기능이라면 굳이 왜 Pattern 객체를 사용하는 거지?'
하지만 위의 코멘트를 보면서 성능 이슈
가 그 이유라는 걸 알 수 있었는데,
구체적으로 어떤 원리로 String.matches가 Pattern 객체로 compile해 사용하는 것보다 성능 면에서 안 좋은 걸까?
우선, Matcher의 matches()을 활용하면 위와 같이 코드를 짤 수 있는데 구조를 살펴보자!
compile()
메소드이다.matcher(비교할 문자열)
메소드를 사용해서 이 Pattern를 Matcher 객체로 변환해준다.matches()
를 사용하면, 갖고있던 정규식과 비교할 문자열을 비교해서 일치하는지 boolean 값을 반환한다.그렇다면 String.matches(정규식)는 어떤 원리일까?
들여다보니 Pattern의 matches(정규식, 비교할 문자열)
를 호출하고 있었다.
그 속으로 들어가보자!
Pattern.matches(정규식, 비교할 문자열)
은 어떤 원리일까?
메소드를 들여다보니 알게된 점!
너... 똑같은 일을 해주고 있는 아이였구나!
그렇다 결국 String.matches()
는 아래와 같은 Matcher의 matches()
를 활용한 방식을 똑같이 해주는 것이었다.
따라서, String.matches()
가 호출될 때마다 Pattern 클래스의 인스턴스를 생성하므로
String.matches()
를 사용할 때 마다 Pattern 객체가 생성된다.
문제는 Pattern 객체는 생성 비용이 높다는 것이다.
Pattern 클래스는 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 비용이 높다. - 출처 : 이펙티브 자바 / 아이템 [6] - 불필요한 객체생성을 피하라
생성되고 사용이 끝나면 버려지는 즉, 반복될 경우 성능이 안 좋아진다고 할 수 있는 것이었다.
그렇다면, Pattern 객체가 계속 생성되지 않게하는 방법은?
Pattern 객체를 클래스 초기화 과정에서 생성하여 캐싱해두고 재사용하는 것이다!
그렇게되면 isNumber 메소드가 여러번 호출돼도 Pattern 객체가 재생성되지 않아 성능 이슈가 줄어든다!
현지님 하루 하루 성장하고 있네요!! 좋은 내용 감사합니다~ 👍 Go For It 현지