날짜: 2025년 11월 27일
주제: Java I/O 성능 최적화 및 정렬 모델
Collections.sort)는 내부적으로 < (작다) 대신 <= (작거나 같다) 논리를 비교 모델로 사용한다.결론: 실전(코딩 테스트)에서는 무조건
BufferedReader를 사용하는 것이 좋다.
Scanner: 느림 (입력 즉시 파싱)BufferedReader: 매우 빠름 (약 5~10배 빠름)Scanner: 1 KB (작음)BufferedReader: 8 KB (큼)Scanner: 문자를 하나씩 읽으며 정규식 검사 및 파싱 수행BufferedReader: '바구니(Buffer)'에 문자를 가득 찰 때까지 쌓아뒀다가 한 번에 읽음Scanner: nextInt() 등으로 자동 변환 지원BufferedReader: 오직 String 데이터만 가짐 (형변환 필수)Scanner: 불필요BufferedReader: IOException 필수 (throws 처리)CPU와 입출력 장치 사이의 통신 횟수를 줄이는 것이 핵심이다. 물건을 하나씩 낱개로 나르는 것(Scanner)보다, 트럭에 꽉 채워서 한 번에 나르는 것(BufferedReader)이 훨씬 효율적인 원리와 같다.
한 줄의 문자열을 공백 단위로 나눌 때도 성능 차이가 발생한다.
String.split(" "): 정규식(Regex)을 기반으로 동작하므로 내부 연산 비용이 커서 느리다.StringTokenizer: 단순히 공백 문자만 찾아 잘라내므로 빠르다.Tip: 데이터 양이 적다면
split이 편하지만, 10만 개 이상의 데이터라면StringTokenizer를 쓰자.
입력만큼 출력 속도도 중요하다. 반복문 안에서 출력을 계속 호출하면 시간 초과(TLE)의 원인이 된다.
for(int i=0; i<100000; i++) {
System.out.println(i); // 매번 콘솔에 접근하므로 오버헤드가 매우 큼
}
StringBuilder sb = new StringBuilder();
for(int i=0; i<100000; i++) {
sb.append(i).append("\n"); // 문자열을 모아둠 (빠름)
}
System.out.println(sb); // 딱 한 번만 출력