Saya ingin membandingkan baris-baris input string dari stdin menggunakan Python dan C ++ dan terkejut melihat kode C ++ saya menjalankan urutan besarnya lebih lambat daripada kode Python yang setara. Karena C ++ saya berkarat dan saya belum menjadi ahli Pythonista, tolong beri tahu saya jika saya melakukan sesuatu yang salah atau jika saya salah mengerti sesuatu.
(Jawaban TLDR: sertakan pernyataan: cin.sync_with_stdio(false)
atau gunakan fgets
saja.
Hasil TLDR: gulirkan semuanya ke bawah pertanyaan saya dan lihat tabel.)
Kode 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
Setara 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))
Inilah hasil saya:
$ 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
Saya harus mencatat bahwa saya sudah mencoba keduanya di Mac OS X v10.6.8 (Snow Leopard) dan Linux 2.6.32 (Red Hat Linux 6.2). Yang pertama adalah MacBook Pro, dan yang terakhir adalah server yang sangat gemuk, bukan berarti ini terlalu relevan.
$ 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
Adendum dan rekap benchmark kecil
Untuk kelengkapan, saya pikir saya akan memperbarui kecepatan baca untuk file yang sama pada kotak yang sama dengan kode C ++ asli (disinkronkan). Sekali lagi, ini untuk file baris 100 juta pada disk cepat. Inilah perbandingannya, dengan beberapa solusi / pendekatan:
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>
kinerja menyebalkan. Bukan pertama kali itu terjadi. 2) Python cukup pintar untuk tidak menyalin data dalam for for loop karena Anda tidak menggunakannya. Anda dapat menguji ulang mencoba menggunakan scanf
dan a char[]
. Sebagai alternatif, Anda dapat mencoba menulis ulang loop sehingga ada sesuatu yang dilakukan dengan string (mis. Simpan huruf 5 dan hasilkan sebagai hasilnya).
cin.eof()
!! Masukkan getline
panggilan ke dalam pernyataan 'jika`.