본문 바로가기
JAVA/기타

Java Fast I/O 2 (feat. BOJ, StringTokenizer, String.split())

by D.O.T 2024. 7. 6.

이번 포스트에는 StringTokenizer에 대해 작성해보려고 합니다.

PS에서 어떻게든 속도를 조금 더 높여보려고 사람들이 여러 방법을 사용하죠?

그 중 하나가 StringTokenizer 입니다.

 

정말 StringTokenizer의 성능이 그렇게 우수할까?

 

직접 테스트 해봤습니다.

package com.study.datastructrue.string;

import java.util.StringTokenizer;

public class DevidePerformTest {
    public static void main(String[] args) {
       String str = "one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five one two three four five";
       //String str = "일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 일 이 삼 사 오 ";

       long startTime = System.nanoTime();
       String[] splitArray = str.split(" ");
       long endTime = System.nanoTime();
       System.out.println("String.split() time: " + (endTime - startTime) + " ns");

       startTime = System.nanoTime();
       StringTokenizer tokenizer = new StringTokenizer(str);
       endTime = System.nanoTime();
       System.out.println("StringTokenizer time: " + (endTime - startTime) + " ns");

       System.out.println("String.split() result:");
       for (String s : splitArray) {
          System.out.print(s);
       }
       System.out.println();

       System.out.println("StringTokenizer result:");
       while (tokenizer.hasMoreTokens()) {
          System.out.print(tokenizer.nextToken());
       }
    }
}

 

이게 JDK 11이든 21이든 속도가 똑같더라구요.

 

ASCII 기반 짧은 문자열 split() > Tokenizer

ASCII 기반 긴 문자열 split() < Tokenizer

UNICODE 기반 문자열 split() < Tokenizer 

 

이번에는 따로 내부는 뜯어서 설명하지는 않겠습니다. (너무 복잡함)

대신, StringTokenizer를 분석하신 포스트가 있습니다. (여기)

 

보통 PS에서 시간 효율을 크게 따지는 데이터는 N >= 10,000 인 경우가 대다수이니까 StringTokenizer를 사용하는게 좋을 것 같네요. 추가로 해당 포스트에서 자세한 설명을 해두었더라구요.

 

지금 제 테스트 코드의 경우, 구분자를 공백(" ")으로 해두었습니다. 위 포스트에서 말하기를 구분자가 유니코드가 아닌 아스키코드라면, split()이 더 빠르다. (StringTokenizer가 Unicode에 대해 설계하지 않은 Legacy Code이기 때문이다.)

 

감사합니다.