python보다 메모리 관리가 좋은 c++도 종종 시간 초과 문제가 발생합니다.
ios_base::sync_with_studio(false);
cin_tie(NULL);
cout_tie(NULL);
이를 해결하기 위해, 위 코드로 해결하는 사례를 종종 볼 수 있습니다.
이 코드가 어떻게 시간 초과 문제를 해결해 주는지 궁금했습니다.
참고로 아래의 방법은 정공법이 아닌 일종의 편법이므로 통하지 않을 수 있습니다.
1. ios_base::sync_with_studio(false);
<iostream> 헤더를 보면 C++의 표준 입출력은 C와 다르게 구현되어 있음을 알 수 있습니다.
C++에서 입출력 작업을 할 때마다 C의 표준 입출력과 동기화 되도록 설정되어 있는데,
이 과정에서 딜레이가 발생합니다.
따라서, ios_base::sync_with_studio가 이 동기화를 뜻하고, 이를 풀어주어 속도를 올릴 수 있는 것입니다.
그러나 싱글 스레드 환경이 아닌 멀티 스레드 환경에서는 출력 순서가 보장할 수 없어 주의해야 합니다.
코딩 테스트에서는 싱글 스레드만 사용하므로 문제되지 않으므로 적극 사용을 권장합니다.
(실무에서는 C++ 속도를 올리려면 C입출력 사용을 권장합니다.)
또한 위 코드로 동기화를 풀어준다면 C++의 cin과 C의 scanf, gets, getchar 등을
같이 사용할 수 없는 점을 유의해야 합니다.
2. cin.tie(NULL); cout.tie(NULL);
cout << "Hello World";
cin >> num;
C++ 에서는 다른 입출력이 올 때 기존 입출력을 flush (비우기) 합니다.
위의 코드에서도 num을 입력하기 전에 "Hello World"가 나오는 것은 입출력 전에 기존 입출력을 비우기 때문입니다.
cin.tie(NULL); cout.tie(NULL);를 통해 이 tie를 풀어주게 되면 Console에 "Hello World"가 뜨지 않습니다.
입력 전에 무언가 띄우고 싶다면 cout 버퍼를 수동으로 비워주어야 하는 것입니다.
따라서, 위 명령어는 stream을 untie 시켜서 자동적으로 입출력 버퍼를 비우지 않도록 설정해 속도를 높이는 것입니다.
실제 백준에서 여러 알고리즘을 돌려보면 cin, cout untie 시 출력 500만번 기준 8ms 속도가 상승합니다.
3. endl
cout << "안녕하세요" << endl;
C++에서 무언가 출력하고 다음 줄로 넘기려고 하면 보통 위의 코드와 같이 endl 명령어를 추가합니다.
하지만 endl 명령어는 출력 문자를 출력할 뿐만 아니라 출력 버퍼도 비우는 기능을 포함하고 있습니다.
따라서, 출력 버퍼를 비우는 시간 때문에 딜레이가 발생하는 것입니다.
cout << "안녕하세요" << '\n';
코딩테스트에서는 시간 초과 문제가 발생하지 않도록 가능하면 다음과 같이 endl 대신 '\n' 사용하는 것을 권장합니다.