[공부한 것] String.matches는 왜 성능에 안 좋을까?

별의개발자커비·2023년 10월 28일
5

우테코 도전기

목록 보기
20/37

개요

1주차 리뷰를 달던 중 아래와 같은 코멘트를 발견했다.
String.matches가 성능 이슈가 있다고?
정규식 비교는 앞으로도 계속 쓸텐데... 이 부분에 대해 알아봐야겠다는 생각이 들었다!

String.matches의 성능 이슈

나도 따로 Pattern 객체 없이 String.matches를 사용하는 편이었는데, 한 쪽에서는 궁금증이 있었왔다.

'Pattern 객체로 compile해 사용하면 더 코드가 늘어나는데 
같은 기능이라면 굳이 왜 Pattern 객체를 사용하는 거지?'

하지만 위의 코멘트를 보면서 성능 이슈 가 그 이유라는 걸 알 수 있었는데,
구체적으로 어떤 원리로 String.matches가 Pattern 객체로 compile해 사용하는 것보다 성능 면에서 안 좋은 걸까?


Matcher의 matches() 활용

우선, Matcher의 matches()을 활용하면 위와 같이 코드를 짤 수 있는데 구조를 살펴보자!

Pattern

  • Pattern은 문자열이었던 정규식을 적용할 수 있는 형태로 갖고 있는 객체인 것이다.
    이 때, 문자열 -> 적용가능한 형태로 변환해주는 게 compile() 메소드이다.

Matcher

  • Pattern 객체로 갖고 있는 정규식을 비교할 문자열과 함께 사용하려면 Matcher 객체로 만들어줘야한다.
    이때, Pattern의 matcher(비교할 문자열) 메소드를 사용해서 이 Pattern를 Matcher 객체로 변환해준다.

    마지막으로 Mathcer 객체의 matches()를 사용하면, 갖고있던 정규식과 비교할 문자열을 비교해서 일치하는지 boolean 값을 반환한다.

String의 matches() 활용

그렇다면 String.matches(정규식)는 어떤 원리일까?

들여다보니 Pattern의 matches(정규식, 비교할 문자열)를 호출하고 있었다.
그 속으로 들어가보자!


Pattern의 matches() 활용

Pattern.matches(정규식, 비교할 문자열)은 어떤 원리일까?
메소드를 들여다보니 알게된 점!

너... 똑같은 일을 해주고 있는 아이였구나!

그렇다 결국 String.matches()는 아래와 같은 Matcher의 matches()를 활용한 방식을 똑같이 해주는 것이었다.

따라서, String.matches()가 호출될 때마다 Pattern 클래스의 인스턴스를 생성하므로
String.matches() 를 사용할 때 마다 Pattern 객체가 생성된다.

문제는 Pattern 객체는 생성 비용이 높다는 것이다.

Pattern 클래스는 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 비용이 높다. - 출처 : 이펙티브 자바 / 아이템 [6] - 불필요한 객체생성을 피하라

생성되고 사용이 끝나면 버려지는 즉, 반복될 경우 성능이 안 좋아진다고 할 수 있는 것이었다.


결론, Pattern 객체를 캐싱해두기!

그렇다면, Pattern 객체가 계속 생성되지 않게하는 방법은?
Pattern 객체를 클래스 초기화 과정에서 생성하여 캐싱해두고 재사용하는 것이다!

그렇게되면 isNumber 메소드가 여러번 호출돼도 Pattern 객체가 재생성되지 않아 성능 이슈가 줄어든다!

참고한 포스트

5개의 댓글

comment-user-thumbnail
2023년 10월 28일

현지님 하루 하루 성장하고 있네요!! 좋은 내용 감사합니다~ 👍 Go For It 현지

1개의 답글
comment-user-thumbnail
2023년 10월 28일

현지님! 저는 당시 리뷰 답글로 정리했는데
개인적으로 블로그로 matches를 정말 잘 정리해주셔서 아쉬운 마음에... 함께 나누기에 올려주시는 거 어떠세요?!
열심히 작성하셨는데 아쉬워요ㅜ! 😢

1개의 답글