Pemahaman saya adalah bahwa C / C ++ menghasilkan kode native untuk dijalankan pada arsitektur mesin tertentu. Sebaliknya, bahasa seperti Java dan C # berjalan di atas mesin virtual yang mengabstraksi arsitektur asli. Logikanya, tampaknya tidak mungkin bagi Java atau C # untuk menyamai kecepatan C ++ karena langkah perantara ini, namun saya telah diberitahu bahwa kompiler terbaru ("hot spot") dapat mencapai kecepatan ini atau bahkan melampauinya.
Mungkin ini lebih merupakan pertanyaan kompilator daripada pertanyaan bahasa, tetapi adakah yang bisa menjelaskan dalam bahasa Inggris sederhana bagaimana mungkin salah satu bahasa mesin virtual ini berkinerja lebih baik daripada bahasa asli?
Jawaban:
Secara umum, C # dan Java bisa sama cepatnya atau lebih cepat karena kompilator JIT - kompilator yang mengkompilasi IL Anda saat pertama kali dijalankan - dapat membuat pengoptimalan yang tidak bisa dilakukan oleh program yang dikompilasi C ++ karena ia dapat melakukan kueri pada mesin. Ini dapat menentukan apakah mesin itu Intel atau AMD; Pentium 4, Core Solo, atau Core Duo; atau jika mendukung SSE4, dll.
Program C ++ harus dikompilasi terlebih dahulu biasanya dengan pengoptimalan campuran agar dapat berjalan dengan baik di semua mesin, tetapi tidak dioptimalkan sebanyak mungkin untuk konfigurasi tunggal (yaitu prosesor, set instruksi, perangkat keras lain).
Selain itu, fitur bahasa tertentu memungkinkan compiler di C # dan Java membuat asumsi tentang kode Anda yang memungkinkannya mengoptimalkan bagian tertentu yang tidak aman untuk dilakukan compiler C / C ++. Ketika Anda memiliki akses ke pointer, ada banyak pengoptimalan yang tidak aman.
Selain itu, Java dan C # dapat melakukan alokasi heap dengan lebih efisien daripada C ++ karena lapisan abstraksi antara pengumpul sampah dan kode Anda memungkinkannya melakukan semua kompresi heapnya sekaligus (operasi yang cukup mahal).
Sekarang saya tidak dapat berbicara untuk Java pada poin berikutnya ini, tetapi saya tahu bahwa C # misalnya akan benar-benar menghapus metode dan panggilan metode ketika mengetahui tubuh metode kosong. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda.
Jadi seperti yang Anda lihat, ada banyak alasan mengapa implementasi C # atau Java tertentu akan lebih cepat.
Sekarang ini semua dikatakan, pengoptimalan khusus dapat dilakukan di C ++ yang akan menerbangkan apa pun yang dapat Anda lakukan dengan C #, terutama di bidang grafis dan kapan pun Anda dekat dengan perangkat keras. Pointer melakukan keajaiban di sini.
Jadi, tergantung pada apa yang Anda tulis, saya akan memilih salah satunya. Tetapi jika Anda menulis sesuatu yang tidak bergantung pada perangkat keras (driver, permainan video, dll), saya tidak akan khawatir tentang kinerja C # (sekali lagi tidak dapat berbicara tentang Java). Ini akan baik-baik saja.
Di sisi Jawa, @Swati menunjukkan artikel yang bagus:
https://www.ibm.com/developerworks/library/j-jtp09275
sumber
JIT vs. Kompiler Statis
Seperti yang sudah dikatakan di posting sebelumnya, JIT dapat mengkompilasi IL / bytecode menjadi kode native saat runtime. Biaya sebesar itu disebutkan, tetapi tidak sampai pada kesimpulannya:
JIT memiliki satu masalah besar yaitu ia tidak dapat mengkompilasi semuanya: kompilasi JIT membutuhkan waktu, sehingga JIT hanya akan mengkompilasi beberapa bagian kode, sedangkan kompiler statis akan menghasilkan biner asli yang lengkap: Untuk beberapa jenis program, statis kompiler akan dengan mudah mengungguli JIT.
Tentu saja, C # (atau Java, atau VB) biasanya lebih cepat menghasilkan solusi yang layak dan kuat daripada C ++ (jika hanya karena C ++ memiliki semantik yang kompleks, dan pustaka standar C ++, meskipun menarik dan kuat, cukup buruk jika dibandingkan dengan yang lengkap. cakupan pustaka standar dari .NET atau Java), jadi biasanya, perbedaan antara C ++ dan .NET atau Java JIT tidak akan terlihat oleh sebagian besar pengguna, dan untuk biner yang sangat penting, Anda masih dapat memanggil pemrosesan C ++ dari C # atau Java (meskipun panggilan asli semacam ini bisa sangat mahal harganya) ...
Pemrograman C ++
Perhatikan bahwa biasanya, Anda membandingkan kode runtime C ++ dengan padanannya di C # atau Java. Tetapi C ++ memiliki satu fitur yang dapat mengungguli Java / C # di luar kotak, yaitu template metaprograming: Pemrosesan kode akan dilakukan pada waktu kompilasi (dengan demikian, meningkatkan waktu kompilasi secara signifikan), menghasilkan runtime nol (atau hampir nol).
Saya belum begitu melihat efek kehidupan nyata pada ini (saya bermain hanya dengan konsep, tetapi pada saat itu, perbedaannya adalah detik eksekusi untuk JIT, dan nol untuk C ++), tetapi ini layak untuk disebutkan, di samping fakta template metaprograming tidak sepele......
Penggunaan Memori C ++ Asli
C ++ memiliki penggunaan memori yang berbeda dari Java / C #, dan karenanya, memiliki kelebihan / kekurangan yang berbeda.
Tidak peduli optimasi JIT, tidak ada yang akan berjalan secepat akses pointer langsung ke memori (mari kita abaikan sebentar cache prosesor, dll.). Jadi, jika Anda memiliki data yang berdekatan dalam memori, mengaksesnya melalui pointer C ++ (yaitu pointer C ... Mari beri Caesar haknya) akan berjalan kali lebih cepat daripada di Java / C #. Dan C ++ memiliki RAII, yang membuat banyak pemrosesan jauh lebih mudah daripada di C # atau bahkan di Java. C ++ tidak perlu
using
mencakup keberadaan objeknya. Dan C ++ tidak memilikifinally
klausa. Ini bukan sebuah kesalahan.:-)
Dan meskipun struct mirip C # primitif, objek C ++ "pada tumpukan" tidak akan dikenakan biaya pada alokasi dan penghancuran, dan tidak memerlukan GC untuk bekerja di utas independen untuk melakukan pembersihan.
Sedangkan untuk fragmentasi memori, pengalokasi memori pada tahun 2008 bukanlah pengalokasi memori lama dari tahun 1980 yang biasanya dibandingkan dengan GC: Alokasi C ++ tidak dapat dipindahkan ke memori, benar, tetapi kemudian, seperti pada sistem file Linux: Siapa yang membutuhkan hard disk defragmenting saat fragmentasi tidak terjadi? Menggunakan pengalokasi yang tepat untuk tugas yang tepat harus menjadi bagian dari perangkat pengembang C ++. Sekarang, menulis pengalokasi tidaklah mudah, dan kemudian, kebanyakan dari kita memiliki hal-hal yang lebih baik untuk dilakukan, dan untuk sebagian besar penggunaan, RAII atau GC lebih dari cukup.
Sekarang, model memori menjadi lebih rumit dengan munculnya teknologi multicore dan multithreading. Di bidang ini, saya kira .NET memiliki keunggulan, dan Java, saya diberi tahu, memegang posisi teratas. Sangat mudah bagi beberapa hacker "on the bare metal" untuk memuji kode "near the machine" miliknya. Tetapi sekarang, lebih sulit untuk menghasilkan perakitan yang lebih baik dengan tangan daripada membiarkan kompilator menjalankan tugasnya. Untuk C ++, kompilator biasanya menjadi lebih baik daripada peretas sejak satu dekade. Untuk C # dan Java, ini lebih mudah.
Namun, C ++ 0x standar baru akan memberlakukan model memori sederhana ke kompiler C ++, yang akan menstandarisasi (dan dengan demikian menyederhanakan) kode multiprosesing / paralel / threading yang efektif dalam C ++, dan membuat pengoptimalan menjadi lebih mudah dan aman bagi penyusun. Tapi kemudian, kita akan melihat dalam beberapa tahun jika janjinya dipenuhi.
C ++ / CLI vs. C # / VB.NET
Catatan: Di bagian ini, saya berbicara tentang C ++ / CLI, yaitu C ++ yang dihosting oleh .NET, bukan C ++ asli.
Minggu lalu, saya mengikuti pelatihan tentang pengoptimalan .NET, dan menemukan bahwa kompiler statis sangat penting. Sama pentingnya dari JIT.
Kode yang sama yang dikompilasi di C ++ / CLI (atau leluhurnya, Managed C ++) bisa jadi kali lebih cepat daripada kode yang sama yang diproduksi di C # (atau VB.NET, yang kompilernya menghasilkan IL yang sama daripada C #).
Karena kompilator statis C ++ jauh lebih baik untuk menghasilkan kode yang sudah dioptimalkan daripada C #.
Misalnya, fungsi sebaris dalam .NET terbatas pada fungsi yang bytecode-nya kurang atau sama dengan 32 byte. Jadi, beberapa kode dalam C # akan menghasilkan pengakses 40 byte, yang tidak akan pernah di-inline oleh JIT. Kode yang sama di C ++ / CLI akan menghasilkan aksesor 20 byte, yang akan di-inline oleh JIT.
Contoh lain adalah variabel sementara, yang hanya dikompilasi oleh kompilator C ++ sementara masih disebutkan dalam IL yang dihasilkan oleh kompilator C #. Pengoptimalan kompilasi statis C ++ akan menghasilkan lebih sedikit kode, sehingga mengizinkan pengoptimalan JIT yang lebih agresif lagi.
Alasannya berspekulasi adalah fakta bahwa compiler C ++ / CLI mendapatkan keuntungan dari teknik pengoptimalan yang luas dari compiler asli C ++.
Kesimpulan
Saya suka C ++.
Tapi sejauh yang saya lihat, C # atau Java semuanya merupakan taruhan yang lebih baik. Bukan karena mereka lebih cepat dari C ++, tetapi karena ketika Anda menambahkan kualitasnya, mereka akhirnya menjadi lebih produktif, membutuhkan lebih sedikit pelatihan, dan memiliki pustaka standar yang lebih lengkap daripada C ++. Dan untuk sebagian besar program, perbedaan kecepatannya (dengan satu atau lain cara) akan dapat diabaikan ...
Sunting (2011-06-06)
Pengalaman saya di C # /. NET
Saya sekarang memiliki 5 bulan pengkodean C # profesional yang hampir eksklusif (yang menambahkan hingga CV saya sudah penuh dengan C ++ dan Java, dan sentuhan C ++ / CLI).
Saya bermain dengan WinForms (Ahem ...) dan WCF (keren!), Dan WPF (Keren !!!! Baik melalui XAML dan raw C #. WPF sangat mudah Saya percaya Swing tidak bisa dibandingkan dengannya), dan C # 4.0.
Kesimpulannya adalah bahwa meskipun lebih mudah / lebih cepat untuk menghasilkan kode yang berfungsi di C # / Java daripada di C ++, jauh lebih sulit untuk menghasilkan kode yang kuat, aman, dan tangguh di C # (dan bahkan lebih sulit di Java) daripada di C ++. Ada banyak alasan, tetapi dapat diringkas oleh:
using
tidak semudah dan sekuat itu karena menulis implementasi Buang yang benar itu sulit )readonly
dan Javafinal
sama sekali tidak berguna seperti C ++const
( Tidak ada cara Anda dapat mengekspos data kompleks yang hanya dapat dibaca (Pohon Node, misalnya) di C # tanpa kerja yang luar biasa, sementara itu adalah fitur bawaan C ++. Data yang tidak dapat diubah adalah solusi yang menarik , tetapi tidak semuanya bisa dibuat tidak berubah, jadi itu tidak cukup, sejauh ini ).Jadi, C # tetap menjadi bahasa yang menyenangkan selama Anda menginginkan sesuatu yang berhasil, tetapi bahasa yang membuat frustrasi saat Anda menginginkan sesuatu yang selalu dan aman berfungsi.
Java bahkan lebih membuat frustasi, karena memiliki masalah yang sama daripada C #, dan banyak lagi: Kurangnya
using
kata kunci yang setara dengan C # , seorang kolega saya yang sangat terampil menghabiskan terlalu banyak waktu untuk memastikan sumber dayanya dibebaskan dengan benar, sedangkan padanan di C ++ akan mudah (menggunakan destruktor dan petunjuk cerdas).Jadi saya kira keuntungan produktivitas C # / Java terlihat untuk sebagian besar kode ... sampai Anda membutuhkan kode untuk sesempurna mungkin. Hari itu, Anda akan tahu rasa sakit. (Anda tidak akan percaya apa yang diminta dari server dan aplikasi GUI kami ...).
Tentang Java sisi server dan C ++
Saya terus berhubungan dengan tim server (saya bekerja 2 tahun di antara mereka, sebelum kembali ke tim GUI), di sisi lain gedung, dan saya belajar sesuatu yang menarik.
Beberapa tahun terakhir, trennya adalah aplikasi server Java ditakdirkan untuk menggantikan aplikasi server C ++ lama, karena Java memiliki banyak kerangka kerja / alat, dan mudah dipelihara, diterapkan, dll. Dll.
... Sampai masalah latensi rendah muncul beberapa bulan terakhir ini. Kemudian, aplikasi server Java, tidak peduli pengoptimalan yang dilakukan oleh tim Java kami yang terampil, kalah bersaing dengan yang lama, server C ++ yang tidak benar-benar dioptimalkan.
Saat ini, keputusannya adalah mempertahankan server Java untuk penggunaan umum di mana performa masih penting, tidak peduli dengan target latensi rendah, dan secara agresif mengoptimalkan aplikasi server C ++ yang sudah lebih cepat untuk kebutuhan latensi rendah dan latensi ultra-rendah.
Kesimpulan
Tidak ada yang sesederhana yang diharapkan.
Java, dan bahkan lebih banyak lagi C #, adalah bahasa yang keren, dengan pustaka dan kerangka kerja standar yang luas, tempat Anda dapat membuat kode dengan cepat, dan segera mendapatkan hasil.
Tetapi ketika Anda membutuhkan kekuatan mentah, pengoptimalan yang kuat dan sistematis, dukungan kompiler yang kuat, fitur bahasa yang kuat dan keamanan mutlak, Java dan C # mempersulit untuk memenangkan persentase kualitas terakhir yang hilang tetapi penting yang Anda butuhkan untuk tetap berada di atas persaingan.
Seolah-olah Anda membutuhkan lebih sedikit waktu dan pengembang yang kurang berpengalaman di C # / Java daripada di C ++ untuk menghasilkan kode kualitas rata-rata, tetapi di sisi lain, saat Anda membutuhkan kode kualitas yang sangat baik untuk menyempurnakan, tiba-tiba lebih mudah dan lebih cepat untuk mendapatkan hasil tepat di C ++.
Tentu saja, ini adalah persepsi saya sendiri, mungkin terbatas pada kebutuhan khusus kita.
Tapi tetap saja, itulah yang terjadi hari ini, baik di tim GUI dan tim sisi server.
Tentu saja, saya akan memperbarui posting ini jika sesuatu yang baru terjadi.
Sunting (2011-06-22)
Sumber:
Sunting (2011-09-20)
Sumber:
sumber
Setiap kali saya berbicara tentang kinerja yang dikelola vs. tidak terkelola, saya suka menunjukkan seri Rico (dan Raymond) yang membandingkan versi C ++ dan C # dari kamus bahasa Mandarin / Inggris. Pencarian google ini akan membiarkan Anda membaca sendiri, tapi saya suka ringkasan Rico.
Bagi saya intinya adalah dibutuhkan 6 revisi untuk versi yang tidak dikelola untuk mengalahkan versi yang dikelola yang merupakan port sederhana dari kode asli yang tidak dikelola. Jika Anda membutuhkan setiap kinerja terakhir (dan memiliki waktu dan keahlian untuk mendapatkannya), Anda harus tidak dikelola, tetapi bagi saya, saya akan mengambil urutan keuntungan yang saya miliki pada versi pertama di atas 33 % Saya mendapatkan jika saya mencoba 6 kali.
sumber
Kompilasi untuk pengoptimalan CPU tertentu biasanya dinilai terlalu tinggi. Ambil saja program di C ++ dan kompilasi dengan optimasi untuk pentium PRO dan jalankan pada pentium 4. Kemudian kompilasi ulang dengan optimalkan untuk pentium 4. Saya melewati sore yang panjang melakukannya dengan beberapa program. Hasil umum ?? Biasanya peningkatan kinerja kurang dari 2-3%. Jadi keunggulan JIT teoritis hampir tidak ada. Sebagian besar perbedaan kinerja hanya dapat diamati saat menggunakan fitur pemrosesan data skalar, sesuatu yang pada akhirnya memerlukan penyesuaian manual untuk mencapai kinerja maksimum. Pengoptimalan semacam itu lambat dan mahal untuk dilakukan sehingga terkadang tidak cocok untuk JIT.
Di dunia nyata dan aplikasi nyata, C ++ biasanya masih lebih cepat daripada java, terutama karena jejak memori yang lebih ringan yang menghasilkan kinerja cache yang lebih baik.
Tetapi untuk menggunakan semua kemampuan C ++ Anda, pengembang harus bekerja keras. Anda dapat mencapai hasil yang lebih unggul, tetapi Anda harus menggunakan otak Anda untuk itu. C ++ adalah bahasa yang memutuskan untuk memberi Anda lebih banyak alat, dengan harga yang harus Anda pelajari agar dapat menggunakan bahasa dengan baik.
sumber
JIT (Just In Time Compiling) bisa sangat cepat karena dioptimalkan untuk platform target.
Ini berarti ia dapat memanfaatkan trik kompiler apa pun yang dapat didukung oleh CPU Anda, terlepas dari CPU apa yang pengembang tuliskan kode tersebut.
Konsep dasar dari .NET JIT bekerja seperti ini (sangat disederhanakan):
Memanggil metode untuk pertama kali:
Memanggil metode untuk kedua kalinya:
Seperti yang Anda lihat, untuk kedua kalinya, prosesnya hampir sama dengan C ++, kecuali dengan keuntungan dari pengoptimalan waktu nyata.
Meskipun demikian, masih ada masalah overhead lain yang memperlambat bahasa terkelola, tetapi JIT sangat membantu.
sumber
Saya suka jawaban Orion Adrian , tapi ada aspek lain darinya.
Pertanyaan yang sama diajukan puluhan tahun lalu tentang bahasa assembly vs. bahasa "manusia" seperti FORTRAN. Dan sebagian dari jawabannya serupa.
Ya, program C ++ mampu menjadi lebih cepat daripada C # pada algoritme apa pun (non-trivial?), Tetapi program dalam C # sering kali secepat atau lebih cepat daripada implementasi "naif" di C ++, dan versi yang dioptimalkan dalam C ++ akan memakan waktu lebih lama untuk dikembangkan, dan mungkin masih mengalahkan versi C # dengan selisih yang sangat kecil. Jadi, apakah itu sangat berharga?
Anda harus menjawab pertanyaan itu satu per satu.
Meskipun demikian, saya sudah lama menjadi penggemar C ++, dan menurut saya ini adalah bahasa yang sangat ekspresif dan kuat - terkadang kurang dihargai. Tetapi dalam banyak masalah "kehidupan nyata" (bagi saya pribadi, itu berarti "jenis yang harus saya selesaikan"), C # akan menyelesaikan pekerjaan lebih cepat dan lebih aman.
Hukuman terbesar yang Anda bayar? Banyak program .NET dan Java adalah babi memori. Saya telah melihat aplikasi .NET dan Java mengambil "ratusan" megabyte memori, ketika program C ++ dengan kompleksitas yang sama hampir tidak menggores "puluhan" MB.
sumber
Saya tidak yakin seberapa sering Anda akan menemukan bahwa kode Java akan berjalan lebih cepat daripada C ++, bahkan dengan Hotspot, tetapi saya akan menjelaskan bagaimana hal itu bisa terjadi.
Pikirkan kode Java yang dikompilasi sebagai bahasa mesin yang ditafsirkan untuk JVM. Ketika prosesor Hotspot mengetahui bahwa bagian tertentu dari kode yang dikompilasi akan digunakan berkali-kali, ia melakukan pengoptimalan pada kode mesin. Karena Hand-tuning Assembly hampir selalu lebih cepat daripada kode yang dikompilasi C ++, tidak apa-apa untuk mengetahui bahwa kode mesin yang disetel secara terprogram tidak akan terlalu buruk.
Jadi, untuk kode yang sangat berulang, saya bisa melihat di mana memungkinkan Hotspot JVM untuk menjalankan Java lebih cepat dari C ++ ... sampai pengumpulan sampah mulai bekerja. :)
sumber
Since hand-tuning Assembly is almost always faster than C++ compiled code
? Apa yang Anda maksud dengan "Hand-tuning Assembly" dan "C ++ compiled code"?Umumnya, program Anda algoritme akan jauh lebih penting untuk kecepatan aplikasi Anda daripada bahasanya . Anda dapat menerapkan algoritme yang buruk dalam bahasa apa pun, termasuk C ++. Dengan mengingat hal itu, biasanya Anda akan dapat menulis kode yang dijalankan lebih cepat dalam bahasa yang membantu Anda menerapkan algoritme yang lebih efisien.
Bahasa tingkat yang lebih tinggi melakukannya dengan sangat baik dalam hal ini dengan menyediakan akses yang lebih mudah ke banyak struktur data yang dibuat sebelumnya yang efisien dan mendorong praktik yang akan membantu Anda menghindari kode yang tidak efisien. Tentu saja, terkadang mereka juga dapat membuatnya mudah untuk menulis banyak kode yang sangat lambat, jadi Anda masih harus tahu platform Anda.
Juga, C ++ mengejar dengan fitur "baru" (perhatikan tanda kutip) seperti kontainer STL, penunjuk otomatis, dll - lihat pustaka peningkatan, misalnya. Dan terkadang Anda mungkin menemukan bahwa cara tercepat untuk menyelesaikan beberapa tugas memerlukan teknik seperti aritmatika penunjuk yang dilarang dalam bahasa tingkat tinggi - meskipun secara tipikal memungkinkan Anda memanggil pustaka yang ditulis dalam bahasa yang dapat menerapkannya sesuai keinginan. .
Hal utama adalah mengetahui bahasa yang Anda gunakan, itu terkait API, apa yang bisa dilakukannya, dan apa batasannya.
sumber
Saya juga tidak tahu ... program Java saya selalu lambat. :-) Saya tidak pernah benar-benar memperhatikan program C # menjadi sangat lambat.
sumber
Berikut adalah patokan menarik lainnya, yang dapat Anda coba sendiri di komputer Anda sendiri.
Ini membandingkan ASM, VC ++, C #, Silverlight, applet Java, Javascript, Flash (AS3)
Demo kecepatan plugin Roozz
Harap dicatat bahwa kecepatan javascript bervariasi tergantung pada browser apa yang menjalankannya. Hal yang sama juga berlaku untuk Flash dan Silverlight karena plugin ini berjalan dalam proses yang sama seperti browser hosting. Tetapi plugin Roozz menjalankan file .exe standar, yang berjalan dalam prosesnya sendiri, sehingga kecepatannya tidak dipengaruhi oleh browser hosting.
sumber
Anda harus mendefinisikan "kinerja lebih baik dari ..". Yah, saya tahu, Anda bertanya tentang kecepatan, tapi itu bukan segalanya yang penting.
Dan seterusnya, biasnya, ya;)
Dengan C # dan Java Anda membayar harga untuk apa yang Anda dapatkan (pengkodean lebih cepat, manajemen memori otomatis, perpustakaan besar dan sebagainya). Tapi Anda tidak punya banyak ruang untuk tawar-menawar tentang detailnya: ambil paket lengkap atau tidak sama sekali.
Bahkan jika bahasa-bahasa tersebut dapat mengoptimalkan beberapa kode untuk dieksekusi lebih cepat daripada kode yang dikompilasi, keseluruhan pendekatan (IMHO) tidak efisien. Bayangkan mengemudi setiap hari sejauh 5 mil ke tempat kerja Anda, dengan sebuah truk! Nyaman, enak rasanya, Anda aman (zona crumple ekstrim) dan setelah Anda tancap gas beberapa lama, bahkan akan secepat mobil standar! Mengapa kita tidak punya truk untuk dikendarai ke tempat kerja? ;)
Di C ++ Anda mendapatkan apa yang Anda bayar, tidak lebih, tidak lebih sedikit.
Mengutip Bjarne Stroustrup: "C ++ adalah bahasa pengumpulan sampah favorit saya karena menghasilkan sangat sedikit sampah" teks tautan
sumber
times
di shell. Sehingga ia memeriksa seluruh program, bukan hanya satu aspek. Apakah hasilnya serupa?Kode yang dapat dieksekusi yang dihasilkan dari kompilator Java atau C # tidak diinterpretasikan - ia dikompilasi ke kode asli "just in time" (JIT). Jadi, kode pertama kali dalam program Java / C # ditemukan selama eksekusi, ada beberapa overhead saat "kompilator runtime" (alias kompiler JIT) mengubah kode byte (Java) atau kode IL (C #) menjadi instruksi mesin asli. Namun, saat kode tersebut ditemukan saat aplikasi masih berjalan, kode asli segera dijalankan. Ini menjelaskan bagaimana beberapa program Java / C # tampak lambat pada awalnya, tetapi kemudian berkinerja lebih baik semakin lama program tersebut dijalankan. Contoh yang bagus adalah situs web ASP.Net. Pertama kali situs web diakses, mungkin akan sedikit lebih lambat karena kode C # dikompilasi ke kode asli oleh kompiler JIT.
sumber
Beberapa jawaban bagus di sini tentang pertanyaan spesifik yang Anda ajukan. Saya ingin mundur dan melihat gambaran yang lebih besar.
Ingatlah bahwa persepsi pengguna Anda tentang kecepatan perangkat lunak yang Anda tulis dipengaruhi oleh banyak faktor lain selain dari seberapa baik codegen mengoptimalkan. Berikut beberapa contohnya:
Manajemen memori manual sulit dilakukan dengan benar (tidak ada kebocoran), dan bahkan lebih sulit dilakukan dengan efisien (kosongkan memori segera setelah Anda selesai melakukannya). Menggunakan GC, secara umum, lebih mungkin menghasilkan program yang mengelola memori dengan baik. Apakah Anda bersedia bekerja sangat keras, dan menunda pengiriman perangkat lunak Anda, dalam upaya untuk mengalahkan GC?
C # saya lebih mudah dibaca & dipahami daripada C ++ saya. Saya juga memiliki lebih banyak cara untuk meyakinkan diri sendiri bahwa kode C # saya berfungsi dengan benar. Itu berarti saya dapat mengoptimalkan algoritme saya dengan risiko yang lebih kecil untuk menimbulkan bug (dan pengguna tidak menyukai perangkat lunak yang mogok, meskipun itu terjadi dengan cepat!)
Saya dapat membuat perangkat lunak saya lebih cepat di C # daripada di C ++. Itu membebaskan waktu untuk mengerjakan kinerja, dan tetap mengirimkan perangkat lunak saya tepat waktu.
Lebih mudah untuk menulis UI yang bagus di C # daripada C ++, jadi saya lebih mungkin untuk mendorong pekerjaan ke latar belakang sementara UI tetap responsif, atau untuk memberikan UI kemajuan atau dengar ketika program harus memblokir untuk sementara waktu. Ini tidak membuat apa pun lebih cepat, tetapi membuat pengguna lebih senang menunggu.
Semua yang saya katakan tentang C # mungkin benar untuk Java, saya hanya tidak memiliki pengalaman untuk mengatakan dengan pasti.
sumber
Jika Anda seorang programmer Java / C # yang mempelajari C ++, Anda akan tergoda untuk terus memikirkan istilah Java / C # dan menerjemahkan kata demi kata ke sintaks C ++. Dalam hal ini, Anda hanya mendapatkan manfaat yang disebutkan sebelumnya dari kode asli vs. ditafsirkan / JIT. Untuk mendapatkan peningkatan kinerja terbesar dalam C ++ vs. Java / C #, Anda harus belajar berpikir dalam C ++ dan merancang kode secara khusus untuk memanfaatkan kekuatan C ++.
Untuk memparafrasekan Edsger Dijkstra : [bahasa pertama Anda] memutilasi pikiran melampaui pemulihan.
Untuk memparafrasekan Jeff Atwood : Anda dapat menulis [bahasa pertama Anda] dalam bahasa baru apa pun.
sumber
Salah satu pengoptimalan JIT yang paling signifikan adalah metode inlining. Java bahkan dapat menyebariskan metode virtual jika dapat menjamin ketepatan waktu proses. Pengoptimalan semacam ini biasanya tidak dapat dilakukan oleh kompiler statis standar karena memerlukan analisis seluruh program, yang sulit karena kompilasi terpisah (sebaliknya, JIT memiliki semua program yang tersedia untuk itu). Metode penyebarisan meningkatkan pengoptimalan lainnya, memberikan blok kode yang lebih besar untuk dioptimalkan.
Alokasi memori standar di Java / C # juga lebih cepat, dan deallocation (GC) tidak jauh lebih lambat, tetapi hanya kurang deterministik.
sumber
free
dandelete
juga tidak deterministik dan GC dapat dibuat deterministik dengan tidak mengalokasikan.Bahasa mesin virtual tidak mungkin mengungguli bahasa yang dikompilasi tetapi mereka bisa cukup dekat sehingga tidak masalah, karena (setidaknya) alasan berikut (saya berbicara untuk Java di sini karena saya tidak pernah melakukan C #).
1 / Java Runtime Environment biasanya dapat mendeteksi potongan kode yang sering dijalankan dan melakukan kompilasi just-in-time (JIT) dari bagian tersebut sehingga, di masa mendatang, kode tersebut berjalan dengan kecepatan terkompilasi penuh.
2 / Sebagian besar pustaka Java dikompilasi sehingga, saat Anda memanggil fungsi pustaka, Anda menjalankan kode yang dikompilasi, tidak diinterpretasikan. Anda dapat melihat kode (dalam C) dengan mendownload OpenJDK.
3 / Kecuali jika Anda melakukan kalkulasi besar-besaran, sebagian besar waktu program Anda berjalan, program itu menunggu masukan dari manusia yang sangat lambat (secara relatif).
4 / Karena banyak validasi bytecode Java dilakukan pada saat memuat kelas, overhead normal pemeriksaan runtime sangat berkurang.
5 / Pada kasus terburuk, kode intensif kinerja dapat diekstraksi ke modul yang dikompilasi dan dipanggil dari Java (lihat JNI) sehingga berjalan dengan kecepatan penuh.
Singkatnya, bytecode Java tidak akan pernah mengungguli bahasa mesin asli, tetapi ada beberapa cara untuk menguranginya. Keuntungan besar dari Java (seperti yang saya lihat) adalah pustaka standar BESAR dan sifat lintas platform.
sumber
Orion Adrian , izinkan saya membalikkan posting Anda untuk melihat betapa tidak berdasarnya komentar Anda, karena banyak yang dapat dikatakan tentang C ++ juga. Dan mengatakan bahwa compiler Java / C # mengoptimalkan fungsi kosong benar-benar membuat Anda terdengar seperti Anda bukan ahli saya dalam pengoptimalan, karena a) mengapa program nyata harus berisi fungsi kosong, kecuali untuk kode warisan yang sangat buruk, b) itu sebenarnya bukan optimasi hitam dan tepi berdarah.
Terlepas dari frasa itu, Anda secara terang-terangan mengoceh tentang pointer, tetapi bukankah objek di Java dan C # pada dasarnya berfungsi seperti pointer C ++? Mungkinkah mereka tidak tumpang tindih? Mungkinkah mereka tidak nol? C (dan sebagian besar implementasi C ++) memiliki kata kunci pembatasan, keduanya memiliki tipe nilai, C ++ memiliki referensi-ke-nilai dengan jaminan bukan nol. Apa yang ditawarkan Java dan C #?
>>>>>>>>>>
Secara umum, C dan C ++ bisa sama cepat atau lebih cepat karena kompiler AOT - kompiler yang mengkompilasi kode Anda sebelum penerapan, sekali dan untuk semua, pada memori tinggi Anda, banyak server build inti - dapat melakukan pengoptimalan bahwa program kompilasi C # tidak bisa karena punya banyak waktu untuk melakukannya. Kompiler dapat menentukan apakah mesin tersebut Intel atau AMD; Pentium 4, Core Solo, atau Core Duo; atau jika mendukung SSE4, dll, dan jika kompilator Anda tidak mendukung pengiriman runtime, Anda dapat menyelesaikannya sendiri dengan menerapkan beberapa biner khusus.
Program AC # biasanya dikompilasi setelah menjalankannya sehingga berjalan dengan baik di semua mesin, tetapi tidak dioptimalkan sebanyak mungkin untuk satu konfigurasi (yaitu prosesor, set instruksi, perangkat keras lain), dan itu harus menghabiskan waktu pertama. Fitur-fitur seperti fisi loop, inversi loop, vektorisasi otomatis, pengoptimalan seluruh program, perluasan template, IPO, dan banyak lagi, sangat sulit untuk diselesaikan semuanya dan sepenuhnya dengan cara yang tidak mengganggu pengguna akhir.
Selain itu, fitur bahasa tertentu memungkinkan compiler dalam C ++ atau C membuat asumsi tentang kode Anda yang memungkinkannya untuk mengoptimalkan bagian tertentu yang tidak aman untuk dilakukan oleh compiler Java / C #. Ketika Anda tidak memiliki akses ke id tipe lengkap dari generik atau aliran program terjamin, ada banyak pengoptimalan yang tidak aman.
Juga C ++ dan C melakukan banyak alokasi tumpukan sekaligus dengan hanya satu penambahan register, yang tentunya lebih efisien daripada alokasi Javas dan C # seperti untuk lapisan abstraksi antara pengumpul sampah dan kode Anda.
Sekarang saya tidak dapat berbicara untuk Java pada poin berikutnya ini, tetapi saya tahu bahwa compiler C ++ misalnya akan benar-benar menghapus metode dan panggilan metode ketika mengetahui tubuh metode kosong, itu akan menghilangkan subekspresi umum, mungkin mencoba dan mencoba lagi untuk menemukan penggunaan register yang optimal, itu tidak memaksakan pemeriksaan batas, itu akan mengotovektorisasi loop dan loop dalam dan akan membalikkan dalam ke luar, itu memindahkan kondisional keluar dari loop, itu membagi dan membatalkan loop. Ini akan memperluas std :: vector menjadi native zero overhead arrays seperti yang Anda lakukan dengan cara C. Ini akan melakukan optimasi antar prosedural. Ini akan membangun nilai kembali secara langsung di situs pemanggil. Ini akan melipat dan menyebarkan ekspresi. Ini akan menyusun ulang data menjadi cara yang ramah cache. Ini akan melakukan jump threading. Ini memungkinkan Anda menulis pelacak sinar waktu kompilasi dengan overhead waktu proses nol. Ini akan membuat pengoptimalan berbasis grafik yang sangat mahal. Ini akan melakukan pengurangan kekuatan, jika itu menggantikan kode tertentu dengan kode yang secara sintaksis sama sekali tidak sama tetapi secara semantik setara ("xor foo, foo" yang lama hanyalah yang paling sederhana, meskipun pengoptimalan yang sudah ketinggalan zaman dari jenis seperti itu). Jika Anda memintanya dengan ramah, Anda dapat menghilangkan standar titik mengambang IEEE dan mengaktifkan lebih banyak lagi pengoptimalan seperti pemesanan ulang operan titik mengambang. Setelah itu memijat dan membantai kode Anda, itu mungkin mengulangi seluruh proses, karena seringkali, pengoptimalan tertentu meletakkan dasar untuk pengoptimalan yang lebih pasti. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. apakah itu menggantikan kode-kode tertentu dengan kode yang secara sintaksis sama sekali tidak sama tetapi secara semantik setara ("xor foo, foo" yang lama hanyalah pengoptimalan yang paling sederhana, meskipun ketinggalan jaman). Jika Anda memintanya dengan ramah, Anda dapat menghilangkan standar titik mengambang IEEE dan mengaktifkan lebih banyak lagi pengoptimalan seperti pemesanan ulang operan titik mengambang. Setelah itu memijat dan membantai kode Anda, itu mungkin mengulangi seluruh proses, karena seringkali, pengoptimalan tertentu meletakkan dasar untuk pengoptimalan yang lebih pasti. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. apakah itu menggantikan kode-kode tertentu dengan kode yang secara sintaksis sama sekali tidak sama tetapi secara semantik setara ("xor foo, foo" yang lama hanyalah pengoptimalan yang paling sederhana, meskipun ketinggalan jaman). Jika Anda memintanya dengan ramah, Anda dapat menghilangkan standar titik mengambang IEEE dan mengaktifkan lebih banyak lagi pengoptimalan seperti pemesanan ulang operan titik mengambang. Setelah itu memijat dan membantai kode Anda, itu mungkin mengulangi seluruh proses, karena seringkali, pengoptimalan tertentu meletakkan dasar untuk pengoptimalan yang lebih pasti. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. Jika Anda memintanya dengan ramah, Anda dapat menghilangkan standar titik mengambang IEEE dan mengaktifkan lebih banyak lagi pengoptimalan seperti pemesanan ulang operan titik mengambang. Setelah itu memijat dan membantai kode Anda, itu mungkin mengulangi seluruh proses, karena seringkali, pengoptimalan tertentu meletakkan dasar untuk pengoptimalan yang lebih pasti. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. Jika Anda memintanya dengan ramah, Anda dapat menghilangkan standar titik mengambang IEEE dan mengaktifkan lebih banyak lagi pengoptimalan seperti pemesanan ulang operan titik mengambang. Setelah itu memijat dan membantai kode Anda, itu mungkin mengulangi seluruh proses, karena seringkali, pengoptimalan tertentu meletakkan dasar untuk pengoptimalan yang lebih pasti. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda. Mungkin juga mencoba lagi dengan parameter yang diacak dan melihat bagaimana skor varian lain dalam peringkat internalnya. Dan itu akan menggunakan logika semacam ini di seluruh kode Anda.
Jadi seperti yang Anda lihat, ada banyak alasan mengapa implementasi C ++ atau C tertentu akan lebih cepat.
Sekarang ini semua dikatakan, banyak pengoptimalan dapat dilakukan di C ++ yang akan menghilangkan semua yang dapat Anda lakukan dengan C #, terutama di ranah pengolah angka, waktu nyata dan dekat-ke-logam, tetapi tidak secara eksklusif di sana. Anda bahkan tidak perlu menyentuh satu pun penunjuk untuk melangkah jauh.
Jadi, tergantung pada apa yang Anda tulis, saya akan memilih salah satunya. Tetapi jika Anda menulis sesuatu yang tidak bergantung pada perangkat keras (driver, permainan video, dll), saya tidak akan khawatir tentang kinerja C # (sekali lagi tidak dapat berbicara tentang Java). Ini akan baik-baik saja.
<<<<<<<<<<
Secara umum, argumen umum tertentu mungkin terdengar keren di pos tertentu, tetapi umumnya tidak terdengar kredibel.
Bagaimanapun, untuk berdamai: AOT itu bagus, begitu pula JIT . Satu-satunya jawaban yang benar adalah: Tergantung. Dan orang pintar sejati tahu bahwa Anda bisa menggunakan yang terbaik dari kedua dunia itu.
sumber
Ini hanya akan terjadi jika interpreter Java menghasilkan kode mesin yang sebenarnya lebih baik dioptimalkan daripada kode mesin yang dihasilkan compiler Anda untuk kode C ++ yang Anda tulis, sampai pada titik di mana kode C ++ lebih lambat daripada Java dan biaya interpretasinya.
Namun, kemungkinan hal itu benar-benar terjadi cukup rendah - kecuali jika Java memiliki pustaka yang ditulis dengan sangat baik, dan Anda memiliki pustaka C ++ yang ditulis dengan buruk.
sumber
Sebenarnya, C # tidak benar-benar berjalan di mesin virtual seperti Java. IL dikompilasi ke dalam bahasa assembly, yang seluruhnya merupakan kode asli dan berjalan dengan kecepatan yang sama dengan kode asli. Anda dapat melakukan pra-JIT aplikasi .NET yang sepenuhnya menghilangkan biaya JIT dan kemudian Anda menjalankan kode asli sepenuhnya.
Perlambatan dengan .NET akan datang bukan karena kode .NET lebih lambat, tetapi karena ia melakukan lebih banyak hal di belakang layar untuk melakukan hal-hal seperti mengumpulkan sampah, memeriksa referensi, menyimpan bingkai tumpukan lengkap, dll. Ini bisa sangat berguna dan membantu saat membangun aplikasi, tetapi juga membutuhkan biaya. Perhatikan bahwa Anda dapat melakukan semua hal ini dalam program C ++ juga (sebagian besar fungsionalitas inti .NET sebenarnya adalah kode .NET yang dapat Anda lihat di ROTOR). Namun, jika Anda menulis fungsionalitas yang sama, Anda mungkin akan berakhir dengan program yang jauh lebih lambat karena runtime .NET telah dioptimalkan dan disetel dengan baik.
Karena itu, salah satu kekuatan kode yang dikelola adalah dapat sepenuhnya diverifikasi, yaitu. Anda dapat memverifikasi bahwa kode tidak akan pernah mengakses memori proses lain atau melakukan hal-hal yang tidak berguna sebelum Anda menjalankannya. Microsoft memiliki prototipe penelitian dari sistem operasi yang dikelola sepenuhnya yang secara mengejutkan telah menunjukkan bahwa lingkungan yang dikelola 100% sebenarnya dapat bekerja secara signifikan lebih cepat daripada sistem operasi modern mana pun dengan memanfaatkan verifikasi ini untuk mematikan fitur keamanan yang tidak lagi diperlukan oleh program yang dikelola. (kita berbicara seperti 10x dalam beberapa kasus). Radio SE memiliki episode hebat membicarakan proyek ini.
sumber
Dalam beberapa kasus, kode yang dikelola sebenarnya bisa lebih cepat daripada kode asli. Misalnya, algoritme pengumpulan sampah "mark-and-sweep" memungkinkan lingkungan seperti JRE atau CLR untuk membebaskan sejumlah besar objek berumur pendek (biasanya) dalam satu langkah, di mana sebagian besar objek heap C / C ++ dibebaskan satu-at- sebuah waktu.
Dari wikipedia :
Meskipun demikian, saya telah menulis banyak C # dan banyak C ++, dan saya telah menjalankan banyak benchmark. Dalam pengalaman saya, C ++ jauh lebih cepat daripada C #, dalam dua cara: (1) jika Anda mengambil beberapa kode yang telah Anda tulis di C #, masukkan ke C ++ kode asli cenderung lebih cepat. Seberapa cepat? Yah, ini sangat bervariasi, tetapi tidak jarang melihat peningkatan kecepatan 100%. (2) Dalam beberapa kasus, pengumpulan sampah dapat memperlambat aplikasi yang dikelola secara besar - besaran . .NET CLR melakukan pekerjaan yang buruk dengan tumpukan besar (katakanlah,> 2GB), dan dapat menghabiskan banyak waktu di GC - bahkan dalam aplikasi yang memiliki sedikit - atau bahkan tidak ada - objek dari rentang hidup menengah.
Tentu saja, dalam kebanyakan kasus yang saya temui, bahasa terkelola cukup cepat, dengan tembakan panjang, dan pengorbanan pemeliharaan dan pengkodean untuk kinerja ekstra C ++ sama sekali tidak bagus.
sumber
Berikut patokan menarik http://zi.fi/shootout/
sumber
Sebenarnya Sun's HotSpot JVM menggunakan eksekusi "mode campuran". Ini menafsirkan bytecode metode sampai ia menentukan (biasanya melalui penghitung semacam) bahwa blok kode tertentu (metode, loop, blok try-catch, dll.) Akan banyak dieksekusi, kemudian JIT mengkompilasinya. Waktu yang dibutuhkan untuk JIT mengkompilasi metode seringkali memakan waktu lebih lama daripada jika metode itu akan ditafsirkan jika itu adalah metode yang jarang dijalankan. Performa biasanya lebih tinggi untuk "mode campuran" karena JVM tidak membuang waktu JITing kode yang jarang, jika pernah, dijalankan. C # dan .NET jangan lakukan ini. .NET JITs segala sesuatu yang, sering kali, membuang-buang waktu.
sumber
Bacalah tentang HP Labs ' Dynamo , penerjemah untuk PA-8000 yang berjalan pada PA-8000, dan sering kali menjalankan program lebih cepat daripada aslinya. Maka itu tidak akan mengejutkan sama sekali!
Jangan menganggapnya sebagai "langkah perantara" - menjalankan program sudah melibatkan banyak langkah lain, dalam bahasa apa pun.
Itu sering kali bermuara pada:
program memiliki titik panas, jadi meskipun Anda lebih lambat menjalankan 95% dari badan kode yang harus Anda jalankan, Anda masih dapat bersaing dengan kinerja jika Anda lebih cepat di 5% panas
HLL tahu lebih banyak tentang maksud Anda daripada LLL seperti C / C ++, sehingga dapat menghasilkan kode yang lebih dioptimalkan (OCaml memiliki lebih banyak, dan dalam praktiknya seringkali lebih cepat)
kompilator JIT memiliki banyak informasi yang tidak dimiliki oleh kompilator statis (seperti, data aktual yang kebetulan Anda miliki saat ini)
kompiler JIT dapat melakukan pengoptimalan pada waktu proses yang tidak diizinkan oleh linker tradisional (seperti menyusun ulang cabang sehingga kasus umumnya datar, atau panggilan perpustakaan sebaris)
Secara keseluruhan, C / C ++ adalah bahasa yang cukup buruk untuk performa: hanya ada sedikit informasi tentang tipe data Anda, tidak ada informasi tentang data Anda, dan tidak ada runtime dinamis yang memungkinkan banyak hal dalam pengoptimalan waktu proses.
sumber
Anda mungkin mendapatkan semburan singkat saat Java atau CLR lebih cepat daripada C ++, tetapi secara keseluruhan kinerjanya lebih buruk selama masa pakai aplikasi: lihat www.codeproject.com/KB/dotnet/RuntimePerformance.aspx untuk beberapa hasil untuk itu.
sumber
Berikut adalah jawaban dari Cliff Click: http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain
sumber
Itu tidak masuk akal. Penggunaan representasi perantara tidak secara inheren menurunkan kinerja. Misalnya, llvm-gcc mengkompilasi C dan C ++ melalui LLVM IR (yang merupakan mesin register tak terbatas virtual) ke kode asli dan mencapai kinerja yang sangat baik (sering mengalahkan GCC).
Berikut beberapa contohnya:
Mesin virtual dengan kompilasi JIT memfasilitasi pembuatan kode waktu proses (misalnya
System.Reflection.Emit
pada .NET) sehingga Anda dapat mengkompilasi kode yang dihasilkan secara langsung dalam bahasa seperti C # dan F # tetapi harus menggunakan penerjemah yang relatif lambat dalam C atau C ++. Misalnya, untuk menerapkan ekspresi reguler.Bagian-bagian dari mesin virtual (mis. Penghalang tulis dan pengalokasi) sering ditulis dalam assembler yang diberi kode tangan karena C dan C ++ tidak menghasilkan kode yang cukup cepat. Jika sebuah program menekankan bagian-bagian dari sistem ini maka program tersebut dapat mengungguli apa pun yang dapat ditulis dalam C atau C ++.
Penautan dinamis kode asli memerlukan kesesuaian dengan ABI yang dapat menghambat kinerja dan meniadakan pengoptimalan seluruh program sedangkan penautan biasanya ditangguhkan pada VM dan dapat memanfaatkan pengoptimalan seluruh program (seperti obat generik yang direifikasi .NET).
Saya juga ingin membahas beberapa masalah dengan jawaban paercebal yang sangat disukai di atas (karena seseorang terus menghapus komentar saya pada jawabannya) yang menyajikan pandangan terpolarisasi secara kontra-produktif:
Oleh karena itu, pemrograman metaprogram hanya berfungsi jika program tersedia pada waktu kompilasi yang seringkali tidak terjadi, misalnya tidak mungkin untuk menulis pustaka ekspresi reguler yang berkinerja kompetitif di vanilla C ++ karena tidak mampu menghasilkan kode waktu proses (aspek penting dari metaprogramming).
Di C #, itu hanya benar untuk tipe referensi dan tidak benar untuk tipe nilai.
Orang-orang telah mengamati Java mengalahkan C ++ pada tes SOR dari tolok ukur SciMark2 justru karena petunjuk menghalangi pengoptimalan terkait aliasing.
Juga perlu dicatat bahwa .NET melakukan spesialisasi jenis generik di seluruh pustaka yang ditautkan secara dinamis setelah menautkan sedangkan C ++ tidak bisa karena templat harus diselesaikan sebelum menautkan. Dan jelas keuntungan besar yang dimiliki obat generik dibandingkan template adalah pesan kesalahan yang dapat dipahami.
sumber
Di atas apa yang dikatakan beberapa orang lain, dari pemahaman saya. NET dan Java lebih baik dalam alokasi memori. Misalnya, mereka dapat memadatkan memori karena terfragmentasi sedangkan C ++ tidak bisa (aslinya, tetapi bisa jika Anda menggunakan pengumpul sampah yang pintar).
sumber
Untuk apa pun yang membutuhkan banyak kecepatan, JVM hanya memanggil implementasi C ++, jadi ini lebih mempertanyakan seberapa bagus libs mereka daripada seberapa bagus JVM untuk sebagian besar hal terkait OS. Pengumpulan sampah memotong memori Anda menjadi dua, tetapi menggunakan beberapa fitur STL dan Boost yang lebih bagus akan memiliki efek yang sama tetapi dengan potensi bug berkali-kali lipat.
Jika Anda hanya menggunakan pustaka C ++ dan banyak fitur tingkat tingginya dalam proyek besar dengan banyak kelas, Anda mungkin akan berakhir lebih lambat daripada menggunakan JVM. Kecuali jauh lebih rawan kesalahan.
Namun, keuntungan dari C ++ adalah memungkinkan Anda untuk mengoptimalkan diri sendiri, jika tidak, Anda akan terjebak dengan apa yang dilakukan oleh compiler / jvm. Jika Anda membuat container sendiri, menulis manajemen memori Anda sendiri yang selaras, menggunakan SIMD, dan turun ke perakitan di sana-sini, Anda dapat mempercepat setidaknya 2x-4x kali lipat dari apa yang kebanyakan compiler C ++ akan lakukan sendiri. Untuk beberapa operasi, 16x-32x. Itu menggunakan algoritme yang sama, jika Anda menggunakan algoritme yang lebih baik dan memparalelkan, peningkatan bisa dramatis, terkadang ribuan kali lebih cepat daripada metode yang umum digunakan.
sumber
Saya melihatnya dari beberapa sudut pandang yang berbeda.
sumber
Jawaban yang sangat singkat: Dengan anggaran tetap, Anda akan mencapai aplikasi java yang berkinerja lebih baik daripada aplikasi C ++ (pertimbangan ROI) Selain itu, platform Java memiliki profiler yang lebih baik, yang akan membantu Anda menentukan hotspot dengan lebih cepat
sumber