Saya tahu saya cukup sering mendengar bahwa C biasanya memiliki keunggulan kinerja lebih dari C ++. Saya tidak benar-benar memikirkan hal lain sampai saya menyadari bahwa MSVC tampaknya tidak mendukung standar terbaru C, tetapi yang terbaru mendukungnya C99 (sejauh yang saya tahu).
Saya berencana menulis perpustakaan dengan beberapa kode untuk di-render di OpenGL sehingga saya bisa menggunakannya kembali. Saya berencana untuk menulis perpustakaan di C karena setiap peningkatan kinerja diterima ketika datang ke grafis.
Tetapi apakah itu benar-benar layak? Kode yang menggunakan perpustakaan kemungkinan akan ditulis dalam C ++ dan saya lebih suka kode dalam C ++ secara umum.
Namun, jika itu akan menghasilkan bahkan perbedaan kecil dalam kinerja, saya mungkin akan pergi dengan C.
Dapat juga dicatat bahwa perpustakaan ini akan menjadi sesuatu yang akan saya buat untuk bekerja di Windows / OS X / Linux, dan saya mungkin akan mengkompilasi semuanya secara asli (MSVC untuk Windows, Dentang atau GCC untuk OS X, dan GCC untuk Linux .. .atau mungkin kompiler Intel untuk semuanya).
Saya telah melihat sekeliling dan saya telah menemukan beberapa tolok ukur dan semacamnya, tetapi semua yang saya lihat lebih berkaitan dengan GCC daripada MSVC dan Dentang. Juga, tolok ukur tidak menyebutkan standar bahasa yang digunakan. Adakah yang punya pemikiran tentang ini?
EDIT:Saya hanya ingin membagikan sudut pandang saya tentang pertanyaan ini setelah beberapa tahun pengalaman lebih. Saya akhirnya menulis proyek yang saya ajukan pertanyaan ini di C ++. Saya memulai proyek lain sekitar waktu yang sama di C ketika kami mencari untuk keluar dalam jumlah kecil kinerja yang kami bisa dan membutuhkan proyek yang dapat dihubungkan dalam C. Beberapa bulan yang lalu, saya mencapai titik di mana saya benar-benar membutuhkan peta dan maju manipulasi string. Saya tahu kemampuan untuk ini di pustaka standar C ++ dan akhirnya sampai pada kesimpulan bahwa struktur-struktur di pustaka standar kemungkinan akan mengungguli dan lebih stabil daripada peta dan string yang bisa saya implementasikan dalam C dalam jumlah waktu yang wajar. Persyaratan untuk dapat dihubungkan dalam C mudah dipenuhi dengan menulis antarmuka C ke kode C ++, yang dilakukan dengan cepat dengan jenis buram. Menulis ulang pustaka dalam C ++ tampaknya jauh lebih cepat daripada saat menulisnya di C dan kurang rentan terhadap bug, terutama kebocoran memori. Saya juga bisa menggunakan pustaka threading library standar, yang jauh lebih mudah daripada menggunakan implementasi platform-spesifik. Pada akhirnya, saya percaya menulis perpustakaan di C ++ membawa manfaat besar dengan kemungkinan biaya kinerja yang kecil. Saya belum membandingkan versi C ++, tetapi saya percaya bahwa mungkin saja saya telah mendapatkan beberapa kinerja dengan menggunakan struktur data perpustakaan standar daripada yang saya tulis. Saya percaya menulis perpustakaan di C ++ membawa manfaat besar dengan kemungkinan biaya kinerja yang kecil. Saya belum membandingkan versi C ++, tetapi saya percaya bahwa mungkin saja saya telah mendapatkan beberapa kinerja dengan menggunakan struktur data perpustakaan standar daripada yang saya tulis. Saya percaya menulis perpustakaan di C ++ membawa manfaat besar dengan kemungkinan biaya kinerja yang kecil. Saya belum membandingkan versi C ++, tetapi saya percaya bahwa mungkin saja saya telah mendapatkan beberapa kinerja dengan menggunakan struktur data perpustakaan standar daripada yang saya tulis.
Jawaban:
Saya kira orang sering mengklaim bahwa C lebih cepat daripada C ++ karena lebih mudah untuk alasan tentang kinerja dalam C. C ++ secara inheren lebih lambat atau lebih cepat, tetapi kode C ++ tertentu mungkin mengaburkan hukuman kinerja tersembunyi. Misalnya, mungkin ada salinan dan konversi tersirat yang tidak segera terlihat ketika melihat beberapa bagian dari kode C ++.
Mari kita ambil pernyataan berikut:
Mari kita asumsikan lebih lanjut yang
doSomething
memiliki tanda tangan berikut:Sekarang, mari kita coba menganalisis kemungkinan dampak kinerja pernyataan khusus ini.
Dalam C, implikasinya cukup jelas.
foo
hanya dapat menjadi pointer ke struct, dandoSomething
harus menjadi pointer ke suatu fungsi.*c
referensi panjang, dana + 5
penambahan bilangan bulat. Satu-satunya ketidakpastian berasal dari jenisa
: Jika bukan int, akan ada beberapa konversi. tetapi terlepas dari itu, mudah untuk mengukur dampak kinerja dari pernyataan tunggal ini.Sekarang mari kita beralih ke C ++. Pernyataan yang sama sekarang dapat memiliki karakteristik kinerja yang sangat berbeda:
doSomething
bisa berupa fungsi anggota non-virtual (murah), fungsi anggota virtual (sedikit lebih mahal)std::function
,, lambda ... dll. Yang lebih buruk,foo
bisa jadi tipe kelas kelebihan bebanoperator->
dengan beberapa operasi dengan kompleksitas yang tidak diketahui. Jadi, untuk menghitung biaya panggilandoSomething
, sekarang perlu mengetahui sifat pastifoo
dandoSomething
.a
bisa berupa integer, atau referensi ke integer (tipuan tambahan), atau tipe kelas yang mengimplementasikanoperator+(int)
. Operator bahkan dapat mengembalikan tipe kelas lain yang secara implisit dapat dikonversiint
. Sekali lagi, biaya kinerja tidak terlihat dari pernyataan itu sendiri.c
bisa menjadi tipe implementasi kelasoperator*()
. Bisa juga referensi ke yanglong*
lain.Anda mendapatkan fotonya. Karena fitur bahasa C ++, jauh lebih sulit untuk mengukur biaya kinerja pernyataan tunggal daripada di C. Sekarang juga, abstraksi seperti
std::vector
,std::string
umumnya digunakan dalam C ++, yang memiliki karakteristik kinerja sendiri, dan menyembunyikan alokasi memori dinamis ( juga lihat jawaban @ Ian).Jadi, intinya adalah: Secara umum, tidak ada perbedaan dalam kinerja yang mungkin dicapai dengan menggunakan C atau C ++. Tapi untuk kode benar-benar kinerja-kritis, orang biasanya lebih memilih menggunakan C karena ada cara yang kurang mungkin tersembunyi hukuman kinerja.
sumber
Kode yang ditulis dalam C ++ bisa lebih cepat daripada di C, untuk jenis tugas tertentu.
Jika Anda lebih suka C ++, gunakan C ++. Masalah kinerja apa pun akan menjadi tidak signifikan dibandingkan dengan keputusan algoritmik perangkat lunak Anda.
sumber
Salah satu prinsip desain C ++ adalah Anda tidak membayar fitur yang tidak Anda gunakan. Jadi, jika Anda menulis kode dalam C ++ dan menghindari fitur yang tidak ada dalam C, maka kode yang dikompilasi yang dihasilkan harus setara dalam kinerja (meskipun Anda harus mengukur ini).
Ada biaya yang dapat diabaikan untuk menggunakan kelas, misalnya, dibandingkan dengan struct dan banyak fungsi terkait. Fungsi virtual akan sedikit lebih mahal, dan Anda harus mengukur kinerja untuk melihat apakah itu penting untuk aplikasi Anda. Hal yang sama berlaku untuk fitur bahasa C ++ lainnya.
sumber
this
fitur bahasa pointer. Itu saja yang saya katakan.Salah satu alasan mengapa bahasa tingkat yang lebih tinggi kadang-kadang lebih lambat adalah karena mereka dapat bersembunyi di balik layar lebih banyak manajemen memori daripada bahasa tingkat yang lebih rendah.
Bahasa apa pun (atau pustaka, API, dll) yang mengabstraksi detail tingkat rendah berpotensi menyembunyikan operasi yang mahal. Sebagai contoh, dalam beberapa bahasa hanya memotong spasi spasi dari string menghasilkan alokasi memori dan salinan string. Alokasi memori dan penyalinan khususnya bisa menjadi mahal jika terjadi berulang kali dalam satu lingkaran yang ketat.
Jika Anda menulis kode semacam ini dalam C, itu akan menjadi sangat jelas. Dalam C ++ mungkin kurang begitu, karena alokasi dan penyalinan dapat diabstraksi menjadi suatu kelas di suatu tempat. Mereka bahkan mungkin disembunyikan di belakang operator yang kelihatan berlebihan atau copy constructor.
Jadi gunakan C ++ jika Anda mau. Tapi jangan tertipu oleh kenyamanan yang tampak dari abstraksi ketika Anda tidak tahu apa yang ada di bawahnya.
Tentu saja, gunakan profiler untuk mengetahui apa yang sebenarnya memperlambat kode Anda.
sumber
Untuk apa nilainya, saya cenderung menulis perpustakaan saya di C ++ 11 untuk set fitur yang ditingkatkan. Saya suka bisa mengambil keuntungan dari hal-hal seperti pointer bersama, pengecualian, pemrograman generik, dan fitur C ++ lainnya. Saya suka C ++ 11 karena saya menemukan sedikit dukungan pada semua platform yang saya pedulikan. Visual Studio 2013 memiliki banyak fitur bahasa inti dan implementasi perpustakaan yang siap digunakan dan konon sedang bekerja untuk menambahkan sisanya. Seperti yang Anda ketahui, Dentang dan GCC keduanya mendukung seluruh rangkaian fitur juga.
Dengan itu, saya baru-baru ini membaca tentang strategi yang sangat bagus tentang pengembangan perpustakaan yang saya pikir secara langsung relevan dengan permintaan Anda. Artikel tersebut berjudul "Gaya penanganan kesalahan AC yang cocok dengan pengecualian C ++" Stefanu Du Toit menyebut strategi ini sebagai pola "jam pasir". Paragraf pertama artikel:
Sekarang untuk mengatasi masalah utama Anda: kinerja.
Saya akan menyarankan, seperti banyak jawaban lain di sini, bahwa menulis kode dalam kedua bahasa akan bekerja dengan baik pada sudut pandang kinerja. Dari sudut pandang pribadi, saya menemukan menulis kode yang benar dalam C ++ menjadi lebih mudah karena fitur bahasa, tapi saya pikir itu adalah pilihan pribadi. Apa pun itu, kompiler benar-benar pintar dan cenderung menulis kode yang lebih baik daripada Anda. Itu mengatakan bahwa kompiler kemungkinan akan mengoptimalkan kode Anda lebih baik daripada yang Anda bisa.
Saya tahu banyak programmer mengatakan ini, tetapi hal pertama yang harus Anda lakukan adalah menulis kode Anda, lalu buat profil dan optimalkan di mana profiler Anda menyarankan Anda melakukannya. Waktu Anda akan jauh lebih baik dihabiskan untuk menghasilkan fitur dan kemudian mengoptimalkannya setelah Anda dapat melihat di mana kemacetan Anda.
Sekarang untuk beberapa bacaan menyenangkan tentang bagaimana fitur dan optimisasi bahasa dapat benar-benar bekerja sesuai keinginan Anda:
std :: unique_ptr tidak memiliki overhead
constexp memungkinkan untuk perhitungan waktu kompilasi
memindahkan semantik mencegah benda sementara yang tidak perlu
sumber
std::unique_ptr has zero overhead
Ini tidak mungkin benar (secara teknis) karena harus memiliki konstruktornya dipanggil jika stack terurai karena pengecualian. Pointer mentah tidak memiliki overhead ini dan masih benar jika kode Anda mungkin tidak akan melempar. Kompiler tidak akan dapat membuktikan hal ini dalam kasus umum.unique_ptr
? Ini dinyatakannoexcept
, dan paling tidak menangani semua pengecualian, tapi saya tidak bisa membayangkan jenis pengecualian apa yang bisa dilemparkan.Perbedaan kinerja antara C ++ dan C bukan karena apa pun dalam bahasa, secara tegas, tetapi dalam apa yang menggoda Anda untuk melakukannya. Ini seperti kartu kredit vs. uang tunai. Itu tidak membuat Anda menghabiskan lebih banyak, tetapi Anda tetap melakukannya, kecuali jika Anda sangat disiplin.
Berikut adalah contoh dari program yang ditulis dalam C ++, yang kemudian diselaraskan secara agresif. Anda perlu tahu cara melakukan penyetelan kinerja yang agresif, terlepas dari bahasa. Metode yang saya gunakan adalah jeda acak, seperti yang ditunjukkan dalam video ini .
Jenis-jenis hal mahal yang membuat Anda tergoda untuk melakukan C ++ adalah manajemen memori yang berlebihan, pemrograman gaya notifikasi, mempercayai penghitung program Anda ke pustaka abstraksi multi-layer (seperti kata @Ian), bersembunyi lambat, dll.
sumber
C tidak memiliki keunggulan kinerja apa pun dibandingkan dengan C ++ jika Anda melakukan hal yang sama dalam kedua bahasa. Anda dapat mengambil kode C lama yang ditulis oleh programmer C yang layak dan mengubahnya menjadi kode C ++ yang valid dan setara, yang akan berjalan sama cepatnya (kecuali Anda dan kompiler Anda tahu apa yang dilakukan kata kunci "batasan" dan Anda menggunakannya secara efektif, tetapi kebanyakan orang tidak).
C ++ dapat memiliki kinerja yang sangat berbeda, baik lebih lambat atau lebih cepat, jika (1) Anda menggunakan pustaka C ++ standar untuk melakukan hal-hal yang dapat dilakukan lebih cepat dan lebih mudah tanpa menggunakan pustaka, atau (2) jika Anda menggunakan pustaka C ++ standar untuk melakukan hal-hal yang jauh lebih mudah dan lebih cepat daripada dengan mengimplementasikan kembali perpustakaan di C. buruk
sumber