백준에서 입력 속도 테스트를 했을 때 BufferedReader 로 입력을 받으면 0.6585s가 걸리고, Scanner로 입력을 받으면 4.8448s가 걸립니다. 왜 이렇게 속도 차이가 나는지 알아보았습니다.
Scanner
사용법
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// System.in을 입력 스트림으로 하는 Scanner 생성
Scanner scanner = new Scanner(System.in);
// 사용자로부터 입력받기
System.out.println("Enter some text:");
while (scanner.hasNext()) {
String input = scanner.next();
System.out.println("You entered: " + input);
}
// Scanner 닫기
scanner.close();
}
}
내부
...
/**
* Constructs a new {@code Scanner} that produces values scanned
* from the specified input stream. Bytes from the stream are converted
* into characters using the
* {@linkplain Charset#defaultCharset() default charset}.
*
* @param source An input stream to be scanned
* @see Charset#defaultCharset()
*/
public Scanner(InputStream source) {
this(new InputStreamReader(source), WHITESPACE_PATTERN);
}
...
특징
java.util 패키지에 속한 클래스로 입력을 바로 int, short, float, String 등으로 바로 변환하여 읽을 수 있습니다. 또한, 버퍼 크기가 1KB으로 키보드의 입력 작업(I/O)이 발생할 때마다 Scanner로 바로 전달됩니다. Scanner로 전달한 값을 읽는 동안 내부에서 정규 표현식 적용, 입력값 분할, 파싱 과정 등을 거칩니다. 이 특징 때문에 Scanner가 BufferedReader보다 더 느린 성능을 가지게 된 것입니다.
더해서, System.in을 파라미터로 Scanner 생성 시 내부에서 try-catch를 하고 클래스 생성자에서 InputStreamReader를 생성하여 사용하기 때문에 개발자가 직접 해당 작업들을 처리하지 않아도 됩니다.
System.in : 사용자(키보드) 입력 받을 수 있게 하는 정적 변수, 바이트 스트림(InputStream) 형태로 입력값을 읽습니다.
BufferedReader
사용법
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class SimpleBufferedReaderExample {
public static void main(String[] args) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter a line of text:");
try {
String inputLine = bufferedReader.readLine();
System.out.println("You entered: " + inputLine);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// BufferedReader 닫기
bufferedReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
내부
...
/**
* Creates a buffering character-input stream that uses a default-sized
* input buffer.
*
* @param in A Reader
*/
public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
...
특징
java.io 패키지에 속한 클래스로 데이터를 파싱하지 않고 String 으로 값을 받습니다. 또한 버퍼 크기가 8KB이며 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송합니다. 버퍼가 가득 차거나 개행 문자가 나타나면 버퍼의 내용을 한 번에 전송하는 방식으로 Scanner보다 I/O 작업이 줄어들기 때문에 성능이 더 좋습니다. 내부적으로 처리된 것이 없기 때문에 개발자가 직접 IOException 처리와 InputStreamReader를 생성하여 매개변수로 전달해줘야 사용 가능합니다.
동기화가 가능하며 Thread Safe하다는 특징을 가집니다.
InputStreamReader: 입력 장치(키보드 등)으로부터 받은 입력 값을 자바 응용 프로그램으로 전달하는 객체, 바이트 스트림(InputStream) 을 문자 스트림(Reader)로 로 변환해주는 브릿지(bridge) 클래스입니다.
참고
'java|spring' 카테고리의 다른 글
JDK, JRE, JVM (0) | 2024.07.16 |
---|