계기
백준 Java 알고리즘을 풀던 도중 무지성 Scanner 클래스를 사용했다.
다른 사람의 풀이를 보니 BufferedReader를 주로 사용하는 것을 알게 되었고 BufferedReader가 Scanner보다 빠른건 알고 있지만 왜 빠른지 궁금해져서 정리를 하게 되었다.
이를 기록으로 남겨 Scanner와 BufferedReader의 차이점에 대해 알아보고자 한다.
Scanner란?
입력 받은 데이터(바이트)를 다양한 타입으로 변환하여 변환하는 클래스이다.
간단하게 기본형과 String타입을 정규표현식을 사용해 파싱(parse)할 수 있다.
특징
- java.util패키지 안에 들어있다.
- 공백(띄어쓰기) 및 개행(줄 바꿈)을 기준으로 읽는다.
- 원하는 타입으로 읽을 수 있다.
- 버퍼의 사이즈가 **1024바이트(1KB)**이다.
- Thread unsafe 성질을 지니기에 멀티스레드 환경에서 문제가 발생할 수 있다.
- 데이터를 입력받을 경우 즉시 사용자에게 전송되며 입력받을 때마다 전송되어야 하기에 많은 시간이 소요된다.
- UnChecked(Runtime) Exception을 가지고 있어서 버퍼리더와는 다르게 예외 처리를 명시할 필요가 없다.
Scanner 작성법
import java.util.Scanner;
...
Scanner sc = new Scanner(Sysyem.in);
String st = sc.nextLine();
- 위와 같이 System.in을 통해 Scanner 객체를 생성한다.
System.in이란?
사용자들로부터 입력을 받기 위한 입력 스트림이다.
Scanner클래스뿐 아니라 다른 입력 클래스들도 System.in을 통해 사용자 입력을 받아야 한다.
BufferedReader란?
데이터를 한번에 읽어와 버퍼에 보관한 후 버퍼에서 데이터를 읽어오는 방식으로 동작하는 클래스이다.
즉 사용자가 입력한 문자 스트림을 읽는 것(read) 라고 한다.
buffer란?
- 데이터를 한곳에서 다른 한 곳으로 전송하는 동안 일시적으로 해당 데이터를 보관하는 임시 메로리 영역이다.
- 주로 입출력 속도 향상을 위해 버퍼를 사용한다.
- 자바에서는 버퍼를 BufferedReader와 BufferedWriter라는 클래스를 제공하여 다룰 수 있다.
BufferedReader 특징
- java.io 패키지에 속한다.
- 데이터를 파싱하지 않고 String으로만 읽고 가져온다.
- 버퍼의 사이즈가 8192바이트(8KB)이다.
- Checked Exception으로 반드시 예외 처리를 명시해야 한다.
- Thread safe 성징을 지니기에 멀티스레드 환경에서도 안전하다.
- 버퍼가 가득차거나 개행문자가 나타나면 버퍼의 내용을 한번에 프로그램으로 전달하기에 Scanner보다 소요되는 시간을 절약할 수 있다.
BufferedReader 작성법
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOExxception;
...
BufferReader br = new BufferedReader(InputStreamReader(System.in));
String st = br.nextLine();
int a = Integer.parseInt(br.readLine());
int b = Integer.parseInt(st);
- 위와 같이 BufferedReader는 매개변수로 InputStreamReader를 사용하여 객체를 생성한다.
InputStreamreader란?
문자 기반의 보조 스트림으로써 바이트 기반 스트림을 문자 기반 스트림으로 연결시켜 주는 역할을 한다.
바이트 스트림 -> 문자 스트림
또한 패키지의 경우 java.io 하위에 BufferedReader, InputStreamReader와 예외처리를 위한 IOException를 사용하며 모두 간단히 java.io.* 로 모두 포함할 수 있다.
Scanner 와 BufferedReader의 차이점
Scanner - Parse로써 사용자가 입력한 텍스트를 token 단위로 잘라 특정한 현태로 반환
BufferedReader는 Read로 사용자가 입력한 데이터 자체를 그대로 읽어 들이는 것
1. Scanner는 BufferedReader보다 타입에 구애받지 않는다.
- BufferedReader는 String 형식으로만 읽고 저장하기에 형변환을 위한 추가적인 코드 작성이 불가피한 반면에 Scanner는 원하는 타입으로 읽고 파싱할 수 있다.
- Scanner의 경우 int, long, short, float, double의 경우 next???()같은 함수들을 사용할 수 있다.
- BufferedReader는 readLine()함수만을 사용한다.
2. BufferedReader는 Scanner보다 효율적인 메모리 용량을 가진다.
- BufferedReader의 버퍼 메모리가 8KB로 Scanner의 버퍼 메모리 1KB보다 크기에 많은 입력이 있을 경우 더 효율적이다.
- 다만, BufferedReader의 경우 일단 큰 메모리를 잡아먹게 된다.
3. BufferedReader는 Scanner보다 안전하다.
- Scanner는 Thread-unsafe 하기에 멀티스레드 환경에서 안전하지 않지만 BufferedReader는 안전하다.
- 스레드 간 Scanner는 공유할 수 없지만 BufferedReader는 공유할 수 있다.
- 동기화를 지원하는 BuffereadReader는 싱글 스레드인 Scanner보다 약간 느린데, Scanner의 경우 정규식을 사용하여 입력을 받으므로 BufferedReader가 문자열을 더욱 빠르게 입력받을 수 있다.
- Bufferedreader가 Scanner보다 실행 속도가 빠르다.
BufferedReader가 Scanner보다 왜 빠를까?
- 문자가 입력될 때마다 CPU가 하나하나 입출력을 하는 것보다 버퍼에 어느정도 쌓아두고 가득 차거나 개행이 일어날 때마다 입출력을 처리하는 것이 훨씬 효율적이다.
참고
'BackEnd > Java' 카테고리의 다른 글
Spring의 3대 요소 (IoC, DI, PSA, AOP) (0) | 2023.10.13 |
---|---|
[자료 구조] - 자료구조와 배열, 리스트에 대해 알아보자 - Java (0) | 2023.08.24 |
Spring Boot 설치 세팅 (STS 설치) - Oracle, Mybatis (4) | 2023.02.06 |
자바 Java JDK 설치하기 (0) | 2023.02.05 |