Tôi muốn so sánh các dòng đọc chuỗi đầu vào từ stdin bằng Python và C ++ và đã bị sốc khi thấy mã C ++ của tôi chạy chậm hơn so với mã Python tương đương. Vì C ++ của tôi bị gỉ và tôi chưa phải là chuyên gia Pythonista, vui lòng cho tôi biết nếu tôi làm sai hoặc nếu tôi hiểu nhầm điều gì đó.
(Câu trả lời TLDR: bao gồm câu lệnh: cin.sync_with_stdio(false)
hoặc chỉ sử dụng fgets
thay thế.
Kết quả TLDR: cuộn toàn bộ xuống cuối câu hỏi của tôi và nhìn vào bảng.)
Mã C ++:
#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;
}
// Compiled with:
// g++ -O3 -o readline_test_cpp foo.cpp
Python tương đương:
#!/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))
Đây là kết quả của tôi:
$ 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
Tôi nên lưu ý rằng tôi đã thử cả hai trong Mac OS X v10.6.8 (Snow Leopard) và Linux 2.6.32 (Red Hat Linux 6.2). Cái trước là MacBook Pro, và cái sau là một máy chủ rất mạnh, không phải cái này quá phù hợp.
$ 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
Phụ lục điểm chuẩn nhỏ và tóm tắt
Để hoàn thiện, tôi nghĩ rằng tôi sẽ cập nhật tốc độ đọc cho cùng một tệp trên cùng một hộp với mã C ++ gốc (được đồng bộ hóa). Một lần nữa, đây là cho một tập tin dòng 100M trên một đĩa nhanh. Đây là so sánh, với một số giải pháp / cách tiếp cận:
Implementation Lines per second
python (default) 3,571,428
cin (default/naive) 819,672
cin (no sync) 12,500,000
fgets 14,285,714
wc (not fair comparison) 54,644,808
<iostream>
hiệu suất tệ. Không phải lần đầu tiên nó xảy ra. 2) Python đủ thông minh để không sao chép dữ liệu trong vòng lặp for vì bạn không sử dụng nó. Bạn có thể kiểm tra lại cố gắng sử dụng scanf
và a char[]
. Ngoài ra, bạn có thể thử viết lại vòng lặp để một cái gì đó được thực hiện với chuỗi (ví dụ: giữ chữ cái thứ 5 và nối nó trong một kết quả).
cin.eof()
!! Đặt getline
cuộc gọi vào câu lệnh 'if`.