문제를 자주 풀다보면 시간이 초과되어 오답으로 처리되는 경우가 있었다.
다른 언어는 잘 모르지만 C++언어에서 입출력을 향상시키는 방법을 몇가지 적어보려고 한다.
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(0); 의미와 장단점
ios_base::sync_with_stdio 구문은 c의 stdio와 c++의 iostream을 동기화시켜주는 역할을 하는데 이 때
iostream과 stdio의 버퍼를 모두 사용하기에 딜레이가 발생한다.
따라서 ios_base::sync_with_stdio(0)를 작성해 동기화를 비활성화 시켜줄 수 있다.
이로 인해 c++만의 독립적인 버퍼 생성, c의 버퍼와 병행할 수는 없지만 사용하는 버퍼의 수가 줄었기에
실행속도는 빨라지게 된다.
알고리즘 문제를 풀 때는 싱글 쓰레드 환경이기에 해당 코드를 추가해도 문제가 발생하지 않을 확률이 높다.
반대로 동기화가 비활성화 됐기 때문에 멀티 쓰레드 환경에서는 출력 순서를 보장할 수 없다.
또한 버퍼가 분리되었기에 C언어 구문과 같이 사용해서는 엉뚱한 결과가 나올 확률이높다.
cin.tie(0); cout.tie(0);
cin.tie(0); 코드는 cin과 cout의 묶음을 풀어준다.
기본적으로 cin과 cout는 묶여있으며 묶여있는 스트림들은 한 스트림이 다른 스트림에서 각 IO작업을 진행하기 전
자동으로 버퍼를 비워줌을 보장한다.
아래의 코드를 예시로 들겠다.
cout << "이름을 입력하시오";
cin >> name;
위 경우 cin과 cout가 묶여있기에, 이름을 입력하기 전 "이름을 입력하시오" 구문이 먼저 출력될 것이다.
하지만, cin.tie(null); 코드를 추가한다면 cin과 cout의 묶음이 풀리면서 "이름을 입력하시오" 라는 구문이 먼저 출력되지도 않았는데 먼저 이름을 입력을 받는 경우가 발생할 수 있다.
이는 cout가 기본적으로 버퍼에 추가되고 바로 비워지지 않기 때문이다.
(출력 명령을 내리거나 버퍼가 가득 찼을 경우에만 버퍼를 비우고 출력한다.)
따라서 cin.tie(null); 코드를 추가했고 name을 입력받기 전에 "이름을 입력하시오" 구문을 먼저 보고 싶다면 cout로
"이름을 입력하시오"를 출력할 때 버퍼를 비워줘야 한다.
마치며.
c++언어를 사용하면서 개행을 endl 구문을 통해 마무리 했는데 endl의 경우 개행 문자 출력과 함께 출력 버퍼를 비우는 역할까지 수행하기 때문에 딜레이가 발생한다고 한다.
따라서, 알고리즘을 풀 때는 실행 속도를 높이기 위해 C 스타일의 '\n'을 통해 개행을 진행하는 걸 권장한다고 한다.
[출처]
'Etc.' 카테고리의 다른 글
[C++] 포인터 (0) | 2024.05.17 |
---|---|
댕글링 포인터(Dangling Pointer) (0) | 2024.05.16 |
[C++] Class (0) | 2024.05.13 |
BaekJoon 1931 문제에서.. (0) | 2024.04.09 |
[C++] Vector와 Deque (0) | 2023.09.26 |