C++로 백준을 풀 때 항상 시간 초과가 난다면 나는 알고리즘의 수정보다는 위의 제목과 같은 구문을 작성해서 기존 코드에 추가했다.
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
근데 이러한 코드가 무슨 의미인지 모르고 사용하고 있으니 궁금하기도 하고, 그래서 구글에서 검색을 하고 정리할 예정이다.
🔎ios_base::sync_with_stdio(false);
ios_base::sync_with_stdio 구문은 c의 stdio와 cpp의 iostream을 동기화시켜주는 역할을 하는데 이때 iostream과 stdio의 버퍼를 모드 사용하기 때문에 딜레이가 발생한다.
따라서 ios_base::sync_with_stdio(false); 코드를 작성함으로써 동기화를 비활성화시켜준다.
그러면 C++만의 독립적인 버퍼가 생성되어 c의 버퍼와 병행하여 사용할 수 없게 되지만, 사용하는 버퍼의 수가 줄어들었기 때문에 실행 속도는 빨라지게 된다.
하지만 동기화된 C++ 버퍼의 경우 thread-safe하기 때문에 모든 I/O의 순서가 예상한 것과 정확히 일치함을 보장할 수 있지만
ios_base::sync_with_stdio(false);를 추가함으로써 동기화가 비활성화됐기 때문에 멀티 스레드 환경에서는 출력 순서를 보장할 수 없습니다.
그리고 버퍼가 분리되었기 때문에 cin과 C의 scanf, gets, getchar 등을 같이 사용하면 안되고, cout와 C의 printf, puts, putchar 등을 사용하면 오류가 발생해서 같이 사용하면 안 된다는 점이 단점이다.
🔎cin,tie(null), cout.tie(null)
default로 cin과 cout는 tie 되어있다.
tie 한다는 것은 두 개의 stream이 sync 되어 있기 때문에 한 스트림에서 다른 스트림이 작업 요청을 하게 되면, 작업했던 내용을 flush 한다는 의미이다.
⚡flush?
buffer에 쌓아둔 데이터를 모두 내보내는(가져오는) 것을 말한다.
기본적으로 tie 되어 있는 스트림들은 한 스트림이 다른 스트림에서 각 IO 작업을 진행하기 전에 자동으로 버퍼를 비워줌을 보장해준다.
cout<< "당신은 몇살이십니가? : ";
cin>>age;
위와 같은 코드가 있을 때 cin과 tie가 묶여있는 경우 나이를 입력하기 전에 "당신은 몇 살이십니까?"가 먼저 출력될 것이다.
하지만 cin.tie(null);코드를 추가한다면 cin과 cout의 tie가 풀리게 되면서 "당신은 몇 살이십니까?"가 출력되기 전에 나이를 입력받는 경우가 발생할 수 있다.
왜냐하면 cout이 기본적으로 버퍼에 추가되고 바로 비워지지 않기 때문이다.
따라서 cin과 cout가 풀려있을 때 출력하고 버퍼를 비워줘야 한다.
👀결론
- sync_with_stdio(false)를 사용하면 c++의 입출력 속도를 향상할수있다.
- 하지만 c와 c++의 입출력 함수를 혼용하면 출력 순서를 보장할 수 없다.
- std::cin.tie(nullptr), std::cout.tie(nullptr)를 하게 되면 flush의 사용이 적어지기 때문에 입출력 속도를 향상시킬 수 있다.
- 하지만 입출력 순서를 보장받을 수 없다.(입력과 출력 각각의 순서는 보장받을 수 있다는 의미)
✔느낀 점
해당 구문이 C++의 실행 속도를 빠르게 한다는 것을 알고있었지만, 어떠한 이유로 향상시키는지 알지 못했는데 생각보다 복잡한 과정을 통해서 실행속도를 향상한다는 것을 깨닫게 되었다.
그리고 항상 나는 코딩할 때 개행 문자를 endl로 작성했지만, endl도 개행문자 \n보다 훨씬 느리다는 것을 알게 되었다.
endl은 줄 바꿈과 동시에 flush [버퍼를 비우기] 하기 때문에 단순 개행 문자보다 느리다.
[출처]
https://jaimemin.tistory.com/1521
ios_base::sync_with_stdio(false); cin.tie(null); 구문을 추가해주는 이유
C++로 알고리즘을 풀 때 실행 속도를 높이기 위해 흔히 아래와 같은 구문을 작성해줍니다. ios_base::sync_with_stdio(false); cin.tie(null); 저 같은 경우 단순히 시간초과가 발생했을 때 남들이 위 코드를 작
jaimemin.tistory.com
https://velog.io/@d2h10s/c-iossyncwithstdio%EB%9E%80
[c++] ios::sync_with_stdio, cin.tie, cout.tie란?
왜 우리는 이 코드를 쓰면 입출력 속도가 빨라지는 걸까요? 한번 파헤쳐봅시다.
velog.io
'Skils > C++' 카테고리의 다른 글
[C++] 공백을 포함한 문자열 처리[getline(),cin.getline(),gets_s(),stringstream] (0) | 2022.06.28 |
---|---|
[C++] range based for(범위기반 for 반복문) (0) | 2022.06.23 |
[C++]-vector 사용법 (0) | 2022.05.03 |
[c++]- map (0) | 2022.05.01 |
C++로 백준을 풀 때 항상 시간 초과가 난다면 나는 알고리즘의 수정보다는 위의 제목과 같은 구문을 작성해서 기존 코드에 추가했다.
ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
근데 이러한 코드가 무슨 의미인지 모르고 사용하고 있으니 궁금하기도 하고, 그래서 구글에서 검색을 하고 정리할 예정이다.
🔎ios_base::sync_with_stdio(false);
ios_base::sync_with_stdio 구문은 c의 stdio와 cpp의 iostream을 동기화시켜주는 역할을 하는데 이때 iostream과 stdio의 버퍼를 모드 사용하기 때문에 딜레이가 발생한다.
따라서 ios_base::sync_with_stdio(false); 코드를 작성함으로써 동기화를 비활성화시켜준다.
그러면 C++만의 독립적인 버퍼가 생성되어 c의 버퍼와 병행하여 사용할 수 없게 되지만, 사용하는 버퍼의 수가 줄어들었기 때문에 실행 속도는 빨라지게 된다.
하지만 동기화된 C++ 버퍼의 경우 thread-safe하기 때문에 모든 I/O의 순서가 예상한 것과 정확히 일치함을 보장할 수 있지만
ios_base::sync_with_stdio(false);를 추가함으로써 동기화가 비활성화됐기 때문에 멀티 스레드 환경에서는 출력 순서를 보장할 수 없습니다.
그리고 버퍼가 분리되었기 때문에 cin과 C의 scanf, gets, getchar 등을 같이 사용하면 안되고, cout와 C의 printf, puts, putchar 등을 사용하면 오류가 발생해서 같이 사용하면 안 된다는 점이 단점이다.
🔎cin,tie(null), cout.tie(null)
default로 cin과 cout는 tie 되어있다.
tie 한다는 것은 두 개의 stream이 sync 되어 있기 때문에 한 스트림에서 다른 스트림이 작업 요청을 하게 되면, 작업했던 내용을 flush 한다는 의미이다.
⚡flush?
buffer에 쌓아둔 데이터를 모두 내보내는(가져오는) 것을 말한다.
기본적으로 tie 되어 있는 스트림들은 한 스트림이 다른 스트림에서 각 IO 작업을 진행하기 전에 자동으로 버퍼를 비워줌을 보장해준다.
cout<< "당신은 몇살이십니가? : "; cin>>age;
위와 같은 코드가 있을 때 cin과 tie가 묶여있는 경우 나이를 입력하기 전에 "당신은 몇 살이십니까?"가 먼저 출력될 것이다.
하지만 cin.tie(null);코드를 추가한다면 cin과 cout의 tie가 풀리게 되면서 "당신은 몇 살이십니까?"가 출력되기 전에 나이를 입력받는 경우가 발생할 수 있다.
왜냐하면 cout이 기본적으로 버퍼에 추가되고 바로 비워지지 않기 때문이다.
따라서 cin과 cout가 풀려있을 때 출력하고 버퍼를 비워줘야 한다.
👀결론
- sync_with_stdio(false)를 사용하면 c++의 입출력 속도를 향상할수있다.
- 하지만 c와 c++의 입출력 함수를 혼용하면 출력 순서를 보장할 수 없다.
- std::cin.tie(nullptr), std::cout.tie(nullptr)를 하게 되면 flush의 사용이 적어지기 때문에 입출력 속도를 향상시킬 수 있다.
- 하지만 입출력 순서를 보장받을 수 없다.(입력과 출력 각각의 순서는 보장받을 수 있다는 의미)
✔느낀 점
해당 구문이 C++의 실행 속도를 빠르게 한다는 것을 알고있었지만, 어떠한 이유로 향상시키는지 알지 못했는데 생각보다 복잡한 과정을 통해서 실행속도를 향상한다는 것을 깨닫게 되었다.
그리고 항상 나는 코딩할 때 개행 문자를 endl로 작성했지만, endl도 개행문자 \n보다 훨씬 느리다는 것을 알게 되었다.
endl은 줄 바꿈과 동시에 flush [버퍼를 비우기] 하기 때문에 단순 개행 문자보다 느리다.
[출처]
https://jaimemin.tistory.com/1521
ios_base::sync_with_stdio(false); cin.tie(null); 구문을 추가해주는 이유
C++로 알고리즘을 풀 때 실행 속도를 높이기 위해 흔히 아래와 같은 구문을 작성해줍니다. ios_base::sync_with_stdio(false); cin.tie(null); 저 같은 경우 단순히 시간초과가 발생했을 때 남들이 위 코드를 작
jaimemin.tistory.com
https://velog.io/@d2h10s/c-iossyncwithstdio%EB%9E%80
[c++] ios::sync_with_stdio, cin.tie, cout.tie란?
왜 우리는 이 코드를 쓰면 입출력 속도가 빨라지는 걸까요? 한번 파헤쳐봅시다.
velog.io
'Skils > C++' 카테고리의 다른 글
[C++] 공백을 포함한 문자열 처리[getline(),cin.getline(),gets_s(),stringstream] (0) | 2022.06.28 |
---|---|
[C++] range based for(범위기반 for 반복문) (0) | 2022.06.23 |
[C++]-vector 사용법 (0) | 2022.05.03 |
[c++]- map (0) | 2022.05.01 |