본문 바로가기
개발/정리

C++ 백준 ios_base::sync_with_stdio(false); cin.tie(null); 구문을 추가해주는 이유

by parkkingcar 2022. 12. 26.

 

C++로 백준이나 알고리즘 문제를 풀 때,  보통 실행속도를 높이기 위해 아래 구문을 사용합니다.

 

#include<iostream>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    // endl (x) -> '\n'사용
    return 0;
}

 

C++의 cin cout scanf printf보다 속도가 느립니다.
출력은 큰 차이는 아니지만 입력같은 경우는 2배 이상의 속도 차이가 난다고 합니다.

 

 

 

실제로  아래글 예시의 입력의 경우, 


scanf를 쓰는 경우 평균 0.9206초가 걸리고,
cin을 쓰는 경우는 평균 2.1742초가 걸립니다.

 

 

출력의 경우,

 

 printf를 쓰는 경우 평균 0.8614초가 걸리고,
cout을 쓰는 경우는 평균 0.9229초가 걸립니다.

 

 

이유는 c의 stdio와 c++의 iostream가 동기화 되고,

이 때 iostreamstdio의 버퍼를 모두 사용하기 때문에 딜레이가 발생합니다.

 

 

 

입력 속도 비교

여러가지 언어와 입력 방법을 이용해서 시간이 얼마나 걸리는지 비교해 보았습니다. 방법: 첫째 줄에 정수의 개수 N (= 10,000,000), 둘째 줄부터 N개의 줄에 한 개의 자연수(10,000 이하)가 적힌 파일

www.acmicpc.net

 

출력 속도 비교

여러가지 언어와 출력 방법을 이용해서 시간이 얼마나 걸리는지 비교해 보았습니다. 방법: 총 N개의 줄에 1부터 10,000,000까지의 자연수를 한 줄에 하나씩 출력하는 시간을 측정. 10번 측정해서 평

www.acmicpc.net

 

 

ios_base::sync_with_stdio(false)

 

 

ios_base::sync_with_stdio(false); 코드를 작성해줌으로써 동기화를 비활성화 시켜줍니다.

 

동기화를 끊음으로서 C++ stream들은 독립적인 buffer를 갖게되고 buffer의 수가 줄어들며 속도가 빨라지게 됩니다.

 

 

 

주의할 점

 

사용시 주의할 점은 동기화가 비활성화됐기 때문에 멀티 쓰레드 환경에서는 출력 순서를 보장할 수 없습니다.

 

또한, 버퍼가 분리되었기 때문에 cin과 C의 scanf, gets, getchar 등을 같이 사용하면 안되고 

cout과 C의 printf, puts, putchar 등을 같이 사용하면 잘못된 결과가 나올 수 있습니다.

 

 

 

cin.tie(null);

 

 

cin.tie(null); 코드는 cin과 cout의 묶음을 풀어줍니다. 

 

기본적으로 cin과 cout은 묶여있고,

묶여있는 스트림들은 한 스트림이 다른 스트림에서 각 IO 작업을 진행하기 전에 자동으로 버퍼를 비워줍니다.

 

 

 

 

결론

따라서 알고리즘을 풀 때는 대부분 싱글 쓰레드 환경이기 때문에

 

ios_base::sync_with_stdio(false); 

코드를 추가해도 결과에 영향이 없으며, C와 C++의 버퍼를 분리하기 때문에 속도가 빨라집니다. 

 

 


 

+++++

 

추가적으로 C++에서 개행을 할 때 endl를 사용하는데,

 

endl의 경우 개행 문자 출력과 함께 출력 버퍼를 비우는 역할까지 같이 하기 때문에 딜레이가 발생합니다.

 

 

따라서, 실행 속도를 높이기 위해 C 스타일의 '\n'을 사용하는것을 추천합니다.

 

 

 

 

 

 

참고

 

Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);

What is the significance of including ios_base::sync_with_stdio(false); cin.tie(NULL); in C++ programs? In my tests, it speeds up the execution time, but is there a test case I should be worried...

stackoverflow.com

 

댓글