백준 코딩테스트 3단계

인공능지연구소·2025년 10월 25일

코딩테스트

목록 보기
3/7
post-thumbnail

입출력 최적화 문제

C++ 입출력의 문제점

cin, cout을 이용한 입출력은 C++의 iostream 버퍼를 사용하는데, 이는 scanf나 printf에 비해 기본 설정이 훨씬 느리게 동작하도록 되어 있다. 이는 스트립의 안정성과 동기화를 보장하기 위해 C의 stdio와 버퍼를 동기화(sync)하기 때문이다. 아무튼 이것을 무시하고 그냥 쓰면 천문학적으로 큰 데이터에서 동작 속도 차이가 크게 발생할 수 있다.

대안1 - C스타일 입출력 사용 (비추천)

scanf("%d", &x)처럼 타입에 맞추어 출력 형식 지정자도 써야하고, 실수하면 컴파일 에러도 발생할 것 이다. 여러모로 편하게 사용할 수 없다.

대안2 - stdio와 동기화 해제 및 cin, cout 묶음 해제 (추천)

다음의 권장 템플릿으로 코드를 작성하면 앞선 문제를 해결할 수 있다.

#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(false); // C의 stdio와 동기화 해제(2배 이상 속도 최적화 가능)
    cin.tie(NULL);               // cin, cout 묶음 해제(입력 후 자동 flush 방지)
    cout.tie(NULL);              // (선택적) 출력 버퍼 묶음 해제

    // 예시
    int n;
    cin >> n;
    cout << n << '\n'; // endl 대신 '\n' 사용
}

대안3 - 대안2와 함께 <bits/stdc++.h> 헤더 사용 (선택적)

우선 이 헤더는 다양한 표준 헤더를 전부 포함하도록 하는 편리한 헤더이다. 그러나 GCC에서만 지원이 되므로, 코테용 웹 컴파일러에 따라 지원이 되지 않는 곳들도 많을 것 이다. 하지만 이것만 추가해도 속도가 상당히 빨라지므로, 사용이 가능하다면 사용해봄직 하다. 참고로 iostream 헤더는 이미 포함되는 것 이므로 추가할 필요가 없음에 유의.

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);              
    cout.tie(NULL);    

    // 예시
    int n;
    cin >> n;
    cout << n << '\n'; // endl 대신 '\n' 사용
}

endl의 문제점

endl은 줄바꿈만 하는 게 아니라 출력 버퍼 비우기(flush) 까지 수행한다. 그래서 코딩테스트에서는 심각한 성능 저하를 유발할 수도 있다(수십 ~ 백배 차이 날 수도 있음).

대안 - \n 사용

\n은 끝에 flush를 수행하지 않기 때문에 훨씬 빠르다. 평소에도 endl 대신 이것을 사용하는 것이 나을 것 이다.

cin EOF 이용하기 문제

cin으로 받을 것이 없는데 다시 cin을 호출하면 EOF(End-of-File) 상태이므로 false를 반환한다. 만약 cin으로 입력을 받는 것을 while 안에 넣는다면, 받을 게 없으면 while을 탈출하는 것이 가능하다. 당연히 break을 사용할 필요도 없다. 사용 예시는 다음과 같다.

int x;
while (cin >> x)
{
	cout << x << "\n";
}
``
profile
내가 뭘 해봤는지는 시리즈 탭에 다 정리해뒀슈

0개의 댓글