일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 데이터구조
- 자료구조
- 컴퓨터공학
- 데이터베이스
- 딥러닝
- 네트워크
- 빅데이터
- 프로그래밍언어
- I'm Sorry
- 소프트웨어공학
- 사이버보안
- Yes
- 소프트웨어
- 파이썬
- 보안
- 버전관리
- 네트워크보안
- 알고리즘
- 클라우드컴퓨팅
- 웹개발
- 프로그래밍
- 컴퓨터비전
- 코딩
- 2
- 머신러닝
- 컴퓨터과학
- 데이터과학
- 자바스크립트
- 데이터분석
- 인공지능
- Today
- Total
스택큐힙리스트
C++에서 stdin에서 줄을 읽는 것이 Python보다 왜 훨씬 느린가요? 본문
저는 파이썬과 C++을 사용하여 stdin에서 문자열 입력 라인을 비교하고 싶었고, C++ 코드가 동등한 파이썬 코드보다 10배 느리게 실행되는 것을 보고 충격을 받았습니다. 제 C++ 지식이 떨어지고 아직 파이썬 전문가가 아니기 때문에, 뭔가를 잘못하고 있는지 또는 잘못 이해하고 있는 것인지 알려주세요.
(요약 답변: cin.sync_with_stdio(false) 문구를 포함하거나 fgets 대신 사용하십시오.)
번역: cin.sync_with_stdio(false) 문구를 포함하거나 fgets 대신 사용하십시오.
결과 요약: 내 질문의 맨 아래로 스크롤해서 표를 확인하십시오.
C++ 코드:
#include
#include
using namespace std;
int main() {
string input_line;
long line_count = 0;
time_t start = time(NULL);
int sec;
int lps;
while (cin) {
getline(cin, input_line);
if (!cin.eof())
line_count++;
};
sec = (int) time(NULL) - start;
cerr << Read << line_count << lines in << sec << seconds.;
if (sec > 0) {
lps = line_count / sec;
cerr << LPS: << lps << endl;
} else
cerr << endl;
return 0;
}
// Compiled with:
// g++ -O3 -o readline_test_cpp foo.cpp
파이썬 상당한 일치:
#!/usr/bin/env python
import time
import sys
count = 0
start = time.time()
for line in sys.stdin:
count += 1
delta_sec = int(time.time() - start_time)
if delta_sec >= 0:
lines_per_sec = int(round(count/delta_sec))
print(Read {0} lines in {1} seconds. LPS: {2}.format(count, delta_sec,
lines_per_sec))
여기는 나의 결과입니다.
$ cat test_lines | ./readline_test_cpp
Read 5570000 lines in 9 seconds. LPS: 618889
$ cat test_lines | ./readline_test.py
Read 5570000 lines in 1 seconds. LPS: 5570000
저는 이를 맥 OS X v10.6.8 (스노우 레오파드)와 리눅스 2.6.32 (레드햇 리눅스 6.2)에서 모두 시도해 보았음을 언급해야 합니다. 전자는 맥북 프로이고, 후자는 매우 강력한 서버이지만 이는 크게 관련이 없습니다.
$ for i in {1..5}; do echo Test run $i at `date`; echo -n CPP:; cat test_lines | ./readline_test_cpp ; echo -n Python:; cat test_lines | ./readline_test.py ; done
Test run 1 at Mon Feb 20 21:29:28 EST 2012
CPP: Read 5570001 lines in 9 seconds. LPS: 618889
Python:Read 5570000 lines in 1 seconds. LPS: 5570000
Test run 2 at Mon Feb 20 21:29:39 EST 2012
CPP: Read 5570001 lines in 9 seconds. LPS: 618889
Python:Read 5570000 lines in 1 seconds. LPS: 5570000
Test run 3 at Mon Feb 20 21:29:50 EST 2012
CPP: Read 5570001 lines in 9 seconds. LPS: 618889
Python:Read 5570000 lines in 1 seconds. LPS: 5570000
Test run 4 at Mon Feb 20 21:30:01 EST 2012
CPP: Read 5570001 lines in 9 seconds. LPS: 618889
Python:Read 5570000 lines in 1 seconds. LPS: 5570000
Test run 5 at Mon Feb 20 21:30:11 EST 2012
CPP: Read 5570001 lines in 10 seconds. LPS: 557000
Python:Read 5570000 lines in 1 seconds. LPS: 5570000
작은 벤치마크 보충 설명 및 요약
완전성을 위해, 같은 상자와 원래 (동기화 된) C ++ 코드로 동일한 파일의 읽기 속도를 업데이트하려고 생각했습니다. 다시 말하지만, 이는 빠른 디스크에서 100M 라인 파일을 대상으로하는 것입니다. 여러 솔루션 / 접근 방법과 함께 비교는 다음과 같습니다 :
답변 1
요약: C++에서 다른 기본 설정 때문에 시스템 호출이 더 필요합니다.
기본적으로 cin은 stdio와 동기화되므로 입력 버퍼링을 피하게 됩니다. 메인의 맨 위에 이것을 추가하면 성능이 훨씬 향상됩니다.
std::ios_base::sync_with_stdio(false);
일반적으로, 입력 스트림이 버퍼링되면 한 번에 한 문자씩 읽는 대신 더 큰 덩어리로 읽을 수 있습니다. 이렇게 하면 일반적으로 비교적 비용이 큰 시스템 호출의 수를 줄일 수 있습니다. 그러나, FILE* 기반 stdio와 iostreams은 종종 별도의 구현과 따로운 버퍼를 가지고 있으므로 두 가지가 동시에 사용되면 문제가 발생할 수 있습니다. 예를 들어:
int myvalue1;
cin >> myvalue1;
int myvalue2;
scanf(%d,&myvalue2);
만약 cin가 실제로 필요한 것보다 더 많은 입력을 읽었다면, 두 번째 정수 값은 자체 독립적인 버퍼를 가진 scanf 함수에 대해 사용할 수 없습니다. 이는 예상치 못한 결과를 초래할 수 있습니다.
이를 피하기 위해 기본적으로 스트림은 stdio와 동기화됩니다. 이를 달성하는 일반적인 방법 중 하나는 stdio 함수를 사용하여 필요할 때마다 각 문자를 하나씩 읽는 것입니다. 그러나 이렇게하면 많은 오버헤드가 발생합니다. 입력 양이 적으면 큰 문제가 되지 않지만, 수백만 줄을 읽을 때는 성능 저하가 상당합니다.
다행히도, 도서관 디자이너들은 당신이 무엇을 하는지 알고 있다면 성능을 개선하기 위해 이 기능을 비활성화할 수 있도록 결정했습니다. 그래서 그들은 sync_with_stdio 방법을 제공했습니다. 이 링크에서 (강조 추가):
동기화가 꺼져 있다면, C++ 표준스트림은 독립적으로 I/O를 버퍼링할 수 있으며, 이는 일부 상황에서 크게 빠를 수 있습니다.
답변 2
Reading lines from stdin in C++ is much slower compared to Python due to several factors. One of the most significant factors is the difference in how each language handles input/output (I/O) operations. In C++, I/O operations are typically performed using the cin and cout objects, which can be slow due to the way they are implemented.On the other hand, Python comes with built-in modules such as sys and io, which provide fast I/O operations. Python's input() and sys.stdin.readline() functions are highly optimized for reading input, making it much faster compared to C++.
Another factor that contributes to the slower performance of C++ when reading from stdin is the way strings are handled. In C++, string objects are typically constructed and destructed for each line read from stdin, which can be slow and inefficient. Python, on the other hand, uses a more optimized string representation, which is faster and more memory-efficient.
Additionally, C++ requires more boilerplate code to read input from stdin compared to Python. This can make reading from stdin more cumbersome and time-consuming, leading to slower performance.
In summary, the slower performance of C++ when reading lines from stdin compared to Python can be attributed to differences in how each language handles I/O operations, how strings are handled, and the amount of boilerplate code required for input reading. To optimize the performance of C++ when reading from stdin, developers can use more efficient I/O operations, optimize string handling, and minimize boilerplate code.