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가 동기화 되고,
이 때 iostream과 stdio의 버퍼를 모두 사용하기 때문에 딜레이가 발생합니다.
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'을 사용하는것을 추천합니다.
참고
'개발 > 정리' 카테고리의 다른 글
[Linux] systemctl 명령 에러 System has not been booted with systemd as init system (PID 1). (1) | 2023.04.11 |
---|---|
웹 브라우저로 개발하기 (온라인 IDE) (1) | 2022.12.28 |
REMIX vs NEXT.JS 비교하기 (1) | 2022.12.23 |
브라우저 렌더링 CSR와 SSR (0) | 2022.12.23 |
google의 새로운 프로그래밍 언어 Carbon (0) | 2022.10.12 |
댓글