스파르타 이노캠/본과정

2023.06.20 화 - 문자열 내 특정 문자열 대체하기

haema_ 2023. 6. 20. 20:08
728x90

오늘 페어 프로그래밍으로 풀었던 알고리즘 문제 중, String에서 특정 문자열을 찾은 후 해당 문자열을 replace하는 문제가 있었다.

찾을 문자열이 여러개여서 arr 배열에 넣은 후 for문을 돌렸는데, for문 안에서 배열의 인덱스 탐색을 위해 증가되는 i의 값과 대체해서 넣을 문자열이 동일해서 str.replaceAll(arr[i] , "" + i ); 의 형태로 작성했었다.

시간 제한이 빠듯하지 않은 문제여서 통과는 무사히 됐지만, 제출 시 다른 알고리즘 문제에 비해 속도가 현저히 느리다는 것을 발견했다.

페어프로그래밍 이전에 이미 해당 알고리즘 문제를 풀어보셨던 조원의 코드는 시간이 꽤 빠르게 나온다고 해서, 그 코드와 비교했더니 로직은 전부 동일한데 replace 구문에서 ~.replace(arr[i], String.valueOf(i))와 같은 형태로 작성된 부분만 달랐다. 그런데 작동 시간은 약 7~80배 정도 차이가 났다.

 

 관련 자료를 찾아 본 결과, ""+i와 같은 형변환은 new StringBuilder("").append(i).toString()와 같은 형태이며, 내부적으로 StringBuilder를 사용해서 형변환을 해주는 구문이다.

 

Java 9부터는, ""+i와 같은 형태는 Invoke Dynamic을 사용해 문자열을 연결하는 방식으로 바뀌었다고 한다.

Ref)

https://www.baeldung.com/java-string-concatenation-invoke-dynamic

 

처음 찾아본 자료에서는 ""+i의 형태가 string으로 변환할 i의 타입을 판단하는 데에 시간이 걸려서 비효율적이다는 글이 대부분이었어서 그런가보다 했는데, 조금 더 찾아보고 조원분과 해당 내용을 공유하다보니 오히려 ""+i가 더 빠르게 동작한다는 자료가 다소 있어서, 실제로 간단한 실험 코드를 작성해본 결과 ""+i형태가 약 2배 정도 빨랐다.

 

 

해당 내용을 바탕으로 프로그래머스에 문의를 넣은 후 답변이 온다면 관련 내용으로 포스팅해보도록 하겠다.

 

사실, 코드를 작성하는 과정에서 String.valueOf()나 Integer.toString()이 떠오르지 않아서 저렇게 작성을 했었는데, 덕분에 관련 정보를 조금 더 찾아볼 수 있었다.

그리고 String.valueOf()는 결국 내부적으로 Integer.toString()을 호출하는 형태라는 사실도 알게 되었다. 그렇게 만들어진 진짜 이유는 어떤건지 알수 없지만, 변환할 매개변수의 타입을 신경쓰지 않고도 String.valueOf()라는 하나의 메서드로 사용할 수 있다는 이점이 있기 때문에 그렇게 사용하는 듯하다. 또, 매개 변수가 Null일 경우 String.valueOf()는 Null자체를 String으로 반환해주는 반면, Integer.toString()은 NullPointerException을 발생시킨다는 차이도 있다.

이런 부분이 결국 객체지향의 최대 장점이면서 동시에 제일 어려운 부분이 아닐까 하는 생각도 들었다.

 

반응형