Saya tidak tahu apakah ini benar, tetapi ketika saya membaca FAQ tentang salah satu masalah dalam menyediakan situs, saya menemukan sesuatu, yang menarik perhatian saya:
Periksa metode input / output Anda. Di C ++, menggunakan cin dan cout terlalu lambat. Gunakan ini, dan Anda akan menjamin tidak dapat menyelesaikan masalah dengan jumlah input atau output yang layak. Gunakan printf dan scanf sebagai gantinya.
Bisakah seseorang tolong klarifikasi ini? Apakah benar-benar menggunakan scanf () dalam program C ++ lebih cepat daripada menggunakan cin >> sesuatu ? Jika ya, apakah itu praktik yang baik untuk menggunakannya dalam program C ++? Saya pikir itu spesifik C, walaupun saya baru belajar C ++ ...
c++
c
performance
io
zeroDivisible
sumber
sumber
Jawaban:
Berikut ini adalah tes cepat untuk kasing sederhana: program untuk membaca daftar angka dari input standar dan XOR semua angka.
versi iostream:
versi scanf:
Hasil
Menggunakan program ketiga, saya membuat file teks yang berisi 33.280.276 angka acak. Waktu eksekusi adalah:
Mengubah pengaturan optimisasi kompiler sepertinya tidak banyak mengubah hasil.
Jadi: memang ada perbedaan kecepatan.
EDIT: Pengguna clyfish menunjukkan di bawah ini bahwa perbedaan kecepatan sebagian besar disebabkan oleh fungsi Iostream I / O yang menjaga sinkronisasi dengan fungsi CI / O. Kami dapat menonaktifkannya dengan panggilan ke
std::ios::sync_with_stdio(false);
:Hasil baru:
C ++ iostream menang! Ternyata sinkronisasi / pembilasan internal inilah yang biasanya memperlambat iostream i / o. Jika kita tidak mencampur stdio dan iostream, kita dapat mematikannya, dan kemudian iostream tercepat.
Kode: https://gist.github.com/3845568
sumber
iostream
hilang ketika Anda mem-parsing lebih dari satu bilangan bulat dalam satuscanf
panggilan.http://www.quora.com/Is-cin-cout-slower-than-scanf-printf/answer/Aditya-Vishwakarma
Kinerja
cin
/cout
bisa lambat karena mereka harus tetap sinkron dengan pustaka C yang mendasarinya. Ini penting jika C IO dan C ++ IO akan digunakan.Namun, jika Anda hanya akan menggunakan C ++ IO, maka cukup gunakan baris di bawah ini sebelum operasi IO.
Untuk info lebih lanjut tentang ini, lihat dokumen libstdc ++ yang sesuai .
sumber
Mungkin scanf agak lebih cepat daripada menggunakan stream. Walaupun stream menyediakan banyak tipe keamanan, dan tidak perlu mengurai string format saat runtime, biasanya stream memiliki keuntungan karena tidak memerlukan alokasi memori yang berlebihan (ini tergantung pada kompiler dan runtime Anda). Yang mengatakan, kecuali kinerja adalah satu-satunya tujuan akhir Anda dan Anda berada di jalur kritis maka Anda harus benar-benar mendukung metode yang lebih aman (lebih lambat).
Ada artikel yang sangat lezat yang ditulis di sini oleh Herb Sutter " The String Formatters of Manor Farm " yang membahas banyak detail tentang kinerja pembuat string
sscanf
danlexical_cast
dan hal-hal seperti apa yang membuatnya berjalan lambat atau cepat. Ini semacam analog, mungkin dengan hal-hal yang akan mempengaruhi kinerja antara gaya C IO dan gaya C ++. Perbedaan utama dengan format cenderung pada keamanan jenis dan jumlah alokasi memori.sumber
Saya baru saja menghabiskan malam mengerjakan masalah di UVa Online (Factovisors, masalah yang sangat menarik, periksa):
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=35&page=show_problem&problem=1080
Saya mendapatkan TLE (batas waktu terlampaui) pada kiriman saya. Pada situs hakim online penyelesaian masalah ini, Anda memiliki batas waktu sekitar 2-3 detik untuk menangani ribuan kasus uji yang berpotensi digunakan untuk mengevaluasi solusi Anda. Untuk masalah intensif komputasi seperti ini, setiap mikrodetik penting.
Saya menggunakan algoritma yang disarankan (baca di forum diskusi untuk situs), tetapi masih mendapatkan TLE.
Saya mengubah "cin >> n >> m" menjadi "scanf ("% d% d ", & n, & m)" dan beberapa "couts" kecil menjadi "printfs", dan TLE saya berubah menjadi "Diterima"!
Jadi, ya, itu bisa membuat perbedaan besar, terutama ketika batas waktu singkat.
sumber
Jika Anda peduli tentang kinerja dan pemformatan string, lihatlah perpustakaan FastFormat Matthew Wilson .
sunting - tautan ke publikasi accu di perpustakaan itu: http://accu.org/index.php/journals/1539
sumber
Ada implementasi stdio ( libio ) yang mengimplementasikan FILE * sebagai C ++ streambuf, dan fprintf sebagai pengurai format runtime. IOstreams tidak perlu parsing format runtime, itu semua dilakukan pada waktu kompilasi. Jadi, dengan backend dibagikan, masuk akal untuk berharap bahwa iostreams lebih cepat saat runtime.
sumber
Ya iostream lebih lambat dari cstdio.
Ya Anda mungkin tidak boleh menggunakan cstdio jika Anda berkembang di C ++.
Karena itu, bahkan ada cara yang lebih cepat untuk mendapatkan I / O daripada memindai jika Anda tidak peduli tentang pemformatan, keamanan jenis, bla, bla, bla ...
Misalnya ini adalah kebiasaan khusus untuk mendapatkan nomor dari STDIN:
sumber
Masalahnya adalah
cin
ada banyak overhead yang terlibat karena memberi Anda lapisan abstraksi di atasscanf()
panggilan. Anda tidak boleh menggunakanscanf()
lebih daricin
jika Anda menulis perangkat lunak C ++ karena yang diinginkancin
adalah untuk. Jika Anda menginginkan kinerja, Anda mungkin tidak akan menulis I / O dalam C ++.sumber
cin
benar-benar lebih "abstrak" (saat runtime) daripadascanf
? Saya tidak berpikir begitu ...scanf
harus menafsirkan string format saat runtime, sedangkan yangiostream
tahu format pada waktu kompilasi.std::istream
dikonfigurasi pada saat runtime (melalui I / O manipulator atau dengan mengatur flag padaistream
objek itu sendiri). SebuahFILE*
objek di sisi lain tidak memiliki negara tersebut, sehingga panggilan untukscanf
dalam hal ini jauh lebih stabil.Pernyataan
cin
dancout
dalam penggunaan umum tampaknya lebih lambat daripadascanf
danprintf
di C ++, tetapi sebenarnya mereka LEBIH CEPAT!Masalahnya adalah: Di C ++, setiap kali Anda menggunakan
cin
dancout
, proses sinkronisasi dilakukan secara default yang memastikan bahwa jika Anda menggunakan keduanyascanf
dancin
dalam program Anda, maka keduanya bekerja sinkron satu sama lain. Proses sinkronisasi ini membutuhkan waktu. Karenanyacin
dancout
MUNCUL menjadi lebih lambat.Namun, jika proses sinkronisasi diatur agar tidak terjadi,
cin
lebih cepat dariscanf
.Untuk melewati proses sinkronisasi, sertakan snipet kode berikut dalam program Anda tepat di awal
main()
:Kunjungi situs ini untuk informasi lebih lanjut.
sumber
Ada bug di akhir file, tetapi kode C ini secara dramatis lebih cepat daripada versi C ++ yang lebih cepat.
C ++ asli mengambil 30 detik kode C mengambil 2 detik.
sumber
Tentu saja konyol menggunakan cstdio di atas iostream. Setidaknya ketika Anda mengembangkan perangkat lunak (jika Anda sudah menggunakan c ++ lebih dari c, maka lanjutkan dan gunakan manfaatnya alih-alih hanya menderita dari kelemahannya).
Tetapi pada juri online Anda tidak sedang mengembangkan perangkat lunak, Anda sedang membuat sebuah program yang seharusnya dapat melakukan hal-hal yang dibutuhkan perangkat lunak Microsoft dalam 60 detik dalam 3 detik !!!
Jadi, dalam hal ini, aturan emasnya seperti (tentu saja jika Anda tidak mendapatkan lebih banyak masalah dengan menggunakan java)
sumber
Bahkan jika
scanf
lebih cepat daricin
itu, itu tidak masalah. Sebagian besar waktu, Anda akan membaca dari hard drive atau keyboard. Memasukkan data mentah ke dalam aplikasi Anda membutuhkan pesanan lebih banyak waktu daripada yang dibutuhkanscanf
ataucin
untuk memprosesnya.sumber
iostream
adalah lebih lambat dari hdd. Ya, itu sangat menyebalkan.