티스토리 뷰

들어가며

회사에서 여유있을때 소스 리팩토링 좀 해보려고 한번씩 쭉 보고 있는데, 문자열 연결하는 부분이 거의 String.format으로 되어있었다.

특별히 이렇게 쓴 이유가 있을까??

이 방식이 다른 방법보다 속도나 성능면에서 우수한걸까??

라는 궁금증으로 시작해 찾아보게 되었다.

 

문자열 연결 방법 및 테스트

1. (+)연산자 (string + string)
2. StringBuilder
3. String.format
(concat, join 등등 여러 방법이 있지만 주로 사용하는 것들 세가지 정도만 테스트해봤다.)

    @Test
    public void 문자열_연결_테스트() {
        final int COUNT = 1000000;
        String header = "앞쪽에 붙일 문자열...";
        String footer = "...뒤에 붙일 문자열";
        String result;
        long startTime;
         
        startTime = System.currentTimeMillis();
        for(int i = 0; i < COUNT; i++) {
            result = header + "중간내용" + footer + "_" + i;
        }
        System.out.println("(+)연산자 : " + (System.currentTimeMillis() - startTime) + "ms");
         
        startTime = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < COUNT; i++) {
            stringBuilder.setLength(0);
            stringBuilder.append(header)
                         .append("중간내용")
                         .append(footer)
                         .append("_")
                         .append(i);
            result = stringBuilder.toString();
        }
        System.out.println("StringBuilder : " + (System.currentTimeMillis() - startTime) + "ms");
         
        startTime = System.currentTimeMillis();
        for(int i = 0; i < COUNT; i++) {
            result = String.format("%s%s%s%s%s", header, "중간내용", footer, "_", i);
        }
        System.out.println("String.format : " + (System.currentTimeMillis() - startTime) + "ms");
     }
 
 
// (+)연산자 : 126ms
// StringBuilder : 56ms
// String.format : 1367ms


1,000,000건 기준으로 StringBuilder가 56ms로 가장 빨랐지만 연결할 문자열이 많아질 경우 가독성은 좋아보이지 않는다.
건수가 많지 않을 경우, 속도차이는 미미했지만 String.format이 좀 더 느린 것을 볼 수 있다.
(ex. 100건 기준 
(+)연산자 : 0ms
StringBuilder : 0ms
String.format : 4ms)

 

결론
//String.format 내부의 parse 메서드
    private static Pattern fsPattern = Pattern.compile(formatSpecifier);

    /**
     * Finds format specifiers in the format string.
     */
    private FormatString[] parse(String s) {
        ArrayList<FormatString> al = new ArrayList<>();
        Matcher m = fsPattern.matcher(s);
        for (int i = 0, len = s.length(); i < len; ) {
            if (m.find(i)) {
            ...

String.format은 첫번째 인자로 정규식을 받기 때문에 Pattern / Matcher 클래스를 생성해준다.

이후 정규식을 검증하는 과정을 거치는데 단순 문자열 연결일 경우 정규식 검증을 위한 클래스 생성과 검증 비용은 불필요하다고 생각한다.

특정 포멧이 필요한게 아니라 단순 문자열 연결일 경우에는 +연산자, StringBuilder를 사용하는 것이 좋다고 생각하며, 건수가 많지 않을 것으로 생각되면 +연산자를 사용해 가독성까지 챙기는게 좋다고 생각한다.

 

Reference
https://kylewbanks.com/blog/java-string-concatenation-vs-stringbuilder-vs-string-format-performance
https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8

 

댓글