왜 C++이 python보다 읽는 속도가 느리죠?

조회수 2833회

python이랑 c++에서 stdin으로부터 한 줄씩 입력받는 프로그램을 돌렸는데 C++이 훨씬 느려요.

보통은 python이 훨씬 느리지 않나요?

제가 코드를 이상하게 짜서 그런가요? 뭐가 잘못된지 모르겠어요

OS X(10.6.8)랑 리눅스(RHEL 6.2)에서 실행했습니다

소스코드1 - c++

C++ code:

#include <iostream>
#include <time.h>

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;
}
//g++ -O3 -o readline_test_cpp foo.cpp로 컴파일

소스코드2 - python

#!/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

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    cinstdio와 동기화(synchronized) 되어 있습니다. 입력 버퍼가 꽉 찰 때까지 기다리지(input buffering) 않고 버퍼에 뭔가 있기만 하면 그냥 갖고 오지요.

    std::ios_base::sync_with_stdio(false);

    를 추가하면 동기화가 해제되어서 속도가 더 빨라질 겁니다.

    buffered input stream은 한 번에 (상대적으로) 엄청 큰 크기의 데이터를 읽어 들입니다. 이렇게 하면 하나씩 읽을 때(cin이 여기에 해당) 보다 system call하는 횟수가 줄어 속도가 훨씬 빨라집니다.

    다만 이 방법은 FILE*에서는 주의해서 써야 합니다. FILE*과 관련해서는 stdioiostream은 구현 방법이 서로 다르고, 그래서 서로 다른 버퍼를 쓰기 때문에 둘을 같이 쓰는 건 권장하지 않습니다.

    예를 들어 다음 코드에서 cinscanf()가 서로 다른 버퍼를 쓰기 때문에 cin이 생각보다 더 많이 읽은 경우, scanf()가 2번째 integer를 읽지 못할 수도 있습니다. 이러면 예기치 못한 상황이 발생할 수도 있지요.

    int myvalue1;
    cin >> myvalue1;
    int myvalue2;
    scanf("%d",&myvalue2);
    

    이런 상황을 피하기 위해 stdiostream과 default값으로 동기화되어 있습니다. 다만 input크기가 커질수록 동기화 한/안한 코드의 속도차가 너무 많이 나기 때문에 std::ios_base::sync_with_stdio(false); 와 같이 프로그래머가 동기화할지 안 할지를 선택할 수 있게 해둔 겁니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)