Seberapa cepatkah C ++ daripada C #?

245

Atau sekarang sebaliknya?

Dari apa yang saya dengar ada beberapa area di mana C # terbukti lebih cepat daripada C ++, tapi saya tidak pernah punya nyali untuk mengujinya sendiri.

Saya kira ada di antara Anda yang bisa menjelaskan perbedaan ini secara terperinci atau mengarahkan saya ke tempat yang tepat untuk mendapatkan informasi mengenai hal ini.

Perangkap
sumber
7
Terlindungi, untuk mencegah agar tolok ukur acak tidak diposting. Jika Anda pikir Anda dapat membuat kasus Anda, Anda perlu 10 rep untuk melakukannya.
Robert Harvey
2
Bagaimana ini tidak ditutup sebagai pendapat / argumentatif? Bukankah saya masih di StackOverflow? (Tidak menyarankan yang dekat, hanya ingin tahu. Saya suka pertanyaan yang memacu argumen yang berargumentasi)
Bill K
1
Ini hampir menjadi pertanyaan yang bisa diperdebatkan, mengingat bahwa kita hidup di zaman di mana IL dapat dikonversi ke CPP dan dioptimalkan dari sana: docs.unity3d.com/Manual/IL2CPP.html
pixelpax
Bahasa yang memeriksa akses array luar tidak akan pernah mengungguli yang tidak.
Seva Alekseyev
@SevaAlekseyev Bukan bahasa yang melakukan ini tetapi kompiler. Salah satu alasan C ++ adalah bahwa cepat (terlepas dari yang jelas) adalah bahwa kompiler C ++ telah ada selama 35 tahun terakhir (jika tidak lebih). Tidak ada yang mencegah kompiler C # menjadi lebih baik dari waktu ke waktu. Untuk kasus yang Anda sebutkan, harap baca stackoverflow.com/questions/16713076/…
Trap

Jawaban:

342

Tidak ada alasan ketat mengapa bahasa berbasis bytecode seperti C # atau Java yang memiliki JIT tidak bisa secepat kode C ++. Namun kode C ++ dulu secara signifikan lebih cepat untuk waktu yang lama, dan juga saat ini masih dalam banyak kasus. Ini terutama disebabkan oleh optimisasi JIT yang lebih maju yang rumit untuk diimplementasikan, dan yang sangat keren baru saja tiba.

Jadi C ++ lebih cepat, dalam banyak kasus. Tetapi ini hanya sebagian dari jawabannya. Kasus-kasus di mana C ++ sebenarnya lebih cepat, adalah program yang sangat dioptimalkan, di mana programmer ahli secara menyeluruh dioptimalkan keluar dari kode. Ini tidak hanya sangat memakan waktu (dan karenanya mahal), tetapi juga umumnya menyebabkan kesalahan karena optimasi yang berlebihan.

Di sisi lain, kode dalam bahasa yang ditafsirkan menjadi lebih cepat di versi runtime yang lebih baru (.NET CLR atau Java VM), tanpa Anda melakukan apa pun. Dan ada banyak optimisasi bermanfaat yang dapat dilakukan oleh kompiler JIT yang tidak mungkin dilakukan dalam bahasa dengan pointer. Juga, beberapa orang berpendapat bahwa pengumpulan sampah umumnya harus secepat atau lebih cepat daripada manajemen memori manual, dan dalam banyak kasus memang demikian. Anda umumnya dapat mengimplementasikan dan mencapai semua ini dalam C ++ atau C, tetapi itu akan menjadi jauh lebih rumit dan rawan kesalahan.

Seperti yang dikatakan Donald Knuth, "optimasi prematur adalah akar dari semua kejahatan". Jika Anda benar-benar tahu pasti bahwa aplikasi Anda sebagian besar akan terdiri dari aritmatika sangat kritis, dan itu akan menjadi hambatan, dan itu pasti akan lebih cepat di C ++, dan Anda yakin bahwa C ++ tidak akan bertentangan dengan yang lain persyaratan, pilih C ++. Dalam kasus lain, berkonsentrasilah pada penerapan pertama aplikasi Anda dengan benar dalam bahasa apa pun yang paling sesuai untuk Anda, kemudian temukan kemacetan kinerja jika berjalan terlalu lambat, dan kemudian pikirkan tentang bagaimana mengoptimalkan kode. Dalam kasus terburuk, Anda mungkin perlu memanggil kode C melalui antarmuka fungsi asing, sehingga Anda masih memiliki kemampuan untuk menulis bagian-bagian penting dalam bahasa tingkat yang lebih rendah.

Ingatlah bahwa relatif mudah untuk mengoptimalkan program yang benar, tetapi jauh lebih sulit untuk memperbaiki program yang dioptimalkan.

Memberikan persentase keuntungan kecepatan yang sebenarnya adalah tidak mungkin, itu sangat tergantung pada kode Anda. Dalam banyak kasus, implementasi bahasa pemrograman bahkan tidak menjadi hambatan. Ambil patokan di http://benchmarksgame.alioth.debian.org/ dengan banyak keraguan, karena ini sebagian besar menguji kode aritmatika, yang kemungkinan besar tidak mirip dengan kode Anda sama sekali.

Martin Probst
sumber
92
Kode <quote> dalam bahasa yang ditafsirkan menjadi lebih cepat di versi runtime yang lebih baru </quote> Karena kode yang dikompilasi oleh versi yang lebih baik dari kompiler juga akan semakin cepat.
Martin York
47
Sebenarnya ada setidaknya satu alasan: JIT harus cepat, dan tidak mampu menghabiskan waktu pada berbagai optimasi lanjutan yang tersedia untuk kompiler C ++.
Nemanja Trifunovic
63
"tetapi juga umumnya mengarah ke kesalahan karena optimasi yang berlebihan." [rujukan sangat dibutuhkan]. Saya bekerja di lab nasional, dan kami mengoptimalkan kode kami. Ini biasanya tidak menghasilkan kode buggy.
Todd Gamblin
35
"Ini relatif mudah untuk mengoptimalkan program yang benar, tetapi jauh lebih sulit untuk memperbaiki program yang dioptimalkan."
gradbot
20
Inge: tidak yakin Anda berada di jalur yang benar di sana. Ya, C # diimplementasikan dalam bahasa lain, tetapi kompiler JIT menghasilkan kode mesin, jadi itu bukan bahasa yang ditafsirkan. Dengan demikian tidak dibatasi oleh implementasi C ++. Saya tidak yakin mengapa Anda berpikir menambahkan beberapa manajer ke sesuatu yang secara inheren membuatnya lebih cepat.
Martin Probst
202

C # mungkin tidak lebih cepat, tetapi itu membuat ANDA / ME lebih cepat. Itu ukuran paling penting untuk apa yang saya lakukan. :)

mattlant
sumber
68
Haha, ada penawaran bagus dari Larry Wall tentang topik ini. Dia berbicara tentang perl, tetapi dapat dipikirkan untuk semua diskusi yang melibatkan bahasa dan kinerja: ".. bahasa komputer sebelumnya, seperti Fortran dan C, dirancang untuk membuat efisien penggunaan perangkat keras komputer yang mahal. Sebaliknya, Perl dirancang untuk membuat efisien menggunakan programmer komputer mahal "
Falaina
60
1. "C # jauh lebih cepat daripada C ++" 2. "Tidak mungkin benar" 1. "Tentu bisa" 2. "Berapa banyak?" 1. "Biasanya dalam 3-4 bulan"
Dmitry S.
2
untuk C ++ yang benar-benar tergantung pada pustaka yang Anda gunakan, C # biasanya tidak lebih cepat, .NET, ketika Anda berbicara produktivitas
Ion Todirel
Itu alasan yang sama mengapa Anda bisa menggunakan Python alih-alih C untuk menulis beberapa kode ... tetapi setelah membuat beberapa perhitungan berat Anda dapat merasakan perbedaan dalam kinerja.
Ch3shire
Itu tergantung pada apa yang Anda terbiasa. Saya memprogram lebih cepat dalam C ++ daripada yang saya miliki di C #. Pengetahuan perpustakaan adalah bagian besar dari itu karena Anda tidak ingin menemukan kembali roda untuk tugas-tugas dasar. C / C ++ masalah utama adalah manajemen pointer yang cukup banyak diselesaikan dengan pointer pintar. Setelah mengatakan bahwa C ++ serius tidak memiliki perpustakaan yang luas seperti .NET dan Java menawarkan dan yang dapat mempercepat pengembangan sebagian besar. Ini tidak akan diselesaikan segera karena anak-anak std itu suka menghabiskan waktu mereka pada perbaikan templat alih-alih ekstensi perpustakaan.
gast128
87

Lima jeruk lebih cepat. Atau lebih tepatnya: tidak ada jawaban selimut (benar). C ++ adalah bahasa yang dikompilasi secara statis (tapi kemudian, ada optimasi dipandu profil juga), C # berjalan dibantu oleh kompiler JIT. Ada begitu banyak perbedaan sehingga pertanyaan-pertanyaan seperti "seberapa cepat" tidak dapat dijawab, bahkan dengan memberi perintah besar.

Konrad Rudolph
sumber
177
Apakah Anda punya bukti untuk mendukung klaim lima jeruk yang keterlaluan? Eksperimen saya semua menunjuk ke 2 jeruk paling banyak, dengan peningkatan 3 mangga ketika melakukan metaprogramming template.
Alex
42
Di ragi dia tidak clamming itu hors d'oeuvres besarnya lebih cepat.
Chris
11
Dari pengalaman saya agak 5,2 jeruk. Tetapi ini tergantung dari buah-o-meter yang Anda gunakan.
Dio F
4
Pembaruan, StackOverflow sendiri kacau dan menangani komentar tidak efisien, sehingga pisang lebih sedikit (300 pisang lebih buruk dari seharusnya): meta.stackexchange.com/questions/254534/…
KeksArmee
87

Saya akan mulai dengan tidak setuju dengan bagian dari jawaban yang diterima (dan diputuskan dengan baik) untuk pertanyaan ini dengan menyatakan:

Sebenarnya ada banyak alasan mengapa kode JITted akan berjalan lebih lambat daripada program C ++ yang dioptimalkan dengan benar (atau bahasa lain tanpa overhead runtime) termasuk:

  • menghitung siklus yang dihabiskan pada kode JITting pada saat runtime menurut definisi tidak tersedia untuk digunakan dalam eksekusi program.

  • setiap jalur panas di JITter akan bersaing dengan kode Anda untuk instruksi dan cache data di CPU. Kita tahu bahwa cache mendominasi dalam hal kinerja dan bahasa asli seperti C ++ tidak memiliki jenis pertikaian ini, menurut definisi.

  • anggaran waktu pengoptimal waktu berjalan tentu jauh lebih terbatas daripada pengoptimal waktu kompilasi (seperti yang ditunjukkan komentator lain)

Intinya: Pada akhirnya, Anda akan hampir pasti dapat membuat implementasi lebih cepat di C ++ dari yang Anda bisa dalam C # .

Sekarang, dengan mengatakan, seberapa cepat sebenarnya tidak dapat diukur, karena ada terlalu banyak variabel: tugas, domain masalah, perangkat keras, kualitas implementasi, dan banyak faktor lainnya. Anda akan menjalankan tes pada skenario Anda untuk menentukan perbedaan dalam kinerja, dan kemudian memutuskan apakah itu sepadan dengan upaya tambahan dan kompleksitas.

Ini adalah topik yang sangat panjang dan kompleks, tetapi saya merasa perlu menyebutkan demi kelengkapan bahwa optimizer runtime C # sangat baik, dan mampu melakukan optimasi dinamis tertentu pada saat runtime yang tidak tersedia untuk C ++ dengan waktu kompilasi ( statis) pengoptimal. Bahkan dengan ini, keuntungannya masih sangat dalam di pengadilan aplikasi asli, tetapi pengoptimal dinamis adalah alasan untuk "kualifikasi hampir pasti" yang diberikan di atas.

-

Dalam hal kinerja relatif, saya juga terganggu oleh angka-angka dan diskusi yang saya lihat di beberapa jawaban lain, jadi saya pikir saya akan berpadu dan pada saat yang sama, memberikan beberapa dukungan untuk pernyataan yang saya buat di atas.

Sebagian besar masalah dengan tolok ukur tersebut adalah Anda tidak dapat menulis kode C ++ seolah-olah Anda sedang menulis C # dan berharap mendapatkan hasil yang representatif (mis. Melakukan ribuan alokasi memori di C ++ akan memberi Anda angka yang mengerikan.)

Alih-alih, saya menulis kode C ++ yang idiomatis dan membandingkannya dengan kode C # @Wiory yang disediakan. Dua perubahan besar yang saya buat pada kode C ++ adalah:

1) menggunakan vektor :: cadangan ()

2) meratakan array 2d menjadi 1d untuk mencapai lokalitas cache yang lebih baik (blok yang berdekatan)

C # (.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

Run time (Release): Init: 124ms, Isi: 165ms

C ++ 14 (Dentang v3.8 / C2)

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

Jalankan waktu (Rilis): Init: 398µs (ya, itu mikrodetik), Isi: 152ms

Total waktu Jalankan: C #: 289ms, C ++ 152ms (kira-kira 90% lebih cepat)

Pengamatan

  • Mengubah implementasi C # ke implementasi array 1d yang sama menghasilkan Init: 40ms, Isi: 171ms, Total: 211ms ( C ++ masih hampir 40% lebih cepat ).

  • Jauh lebih sulit untuk mendesain dan menulis kode "cepat" dalam C ++ daripada menulis kode "biasa" dalam kedua bahasa.

  • Sangat mudah untuk mendapatkan kinerja yang buruk di C ++; kami melihat bahwa dengan kinerja vektor tanpa pagu harga. Dan ada banyak jebakan seperti ini.

  • Kinerja C # agak luar biasa ketika Anda mempertimbangkan semua yang terjadi saat runtime. Dan kinerja itu relatif mudah diakses.

  • Lebih banyak data anekdotal yang membandingkan kinerja C ++ dan C #: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

Intinya adalah bahwa C ++ memberi Anda lebih banyak kontrol atas kinerja. Apakah Anda ingin menggunakan pointer? Referensi? Stack memory? Tumpukan? Polimorfisme dinamis atau menghilangkan overhead runtime dari suatu vtable dengan polimorfisme statis (via templat / CRTP)? Dalam C ++ Anda harus ... er, bisa membuat semua pilihan ini (dan lebih) sendiri, idealnya sehingga solusi terbaik alamat masalah Anda penanggulangan sedang.

Tanyakan pada diri Anda apakah Anda benar-benar ingin atau memerlukan kontrol itu, karena bahkan untuk contoh sepele di atas, Anda dapat melihat bahwa meskipun ada peningkatan kinerja yang signifikan, itu memerlukan investasi yang lebih dalam untuk mengakses.

U007D
sumber
16
@ Quonux terima kasih atas komentarnya. Tentu saja ini bukan "program nyata". Titik tolok ukur adalah refactor tolok ukur C # yang ditawarkan di bagian lain halaman ini sebagai bukti bahwa kode JITted lebih cepat daripada yang asli - bukan, dan tolok ukur itu berpotensi menyesatkan orang baru.
U007D
9
@ Quonux mengapa Anda harus menulis seperti itu? Orang-orang seperti Anda yang membuat saya tidak suka stackoverflow.
Markus Knappen Johansson
5
@MarkusKnappenJohansson Saya mengalami hari yang buruk;), saya juga manusia, menghapus downvote saya, namun pendapat saya masih berlaku. Oh tolong jangan benci SO hanya karena ada beberapa orang "bodoh" :). Selamat menikmati.
Quonux
9
BENCHMARK BENAR-BENAR MENCINTAI. Dalam versi C ++ Anda hanya menyimpan sebagian dari memori (dan kemudian mengagumi bagaimana operasi itu membutuhkan mikrodetik untuk dijalankan). Dalam versi C # Anda membuat 5000 ARRAYS (instantiating objek dalam memori). C ++ lebih cepat daripada C # ... tetapi perbedaannya tidak mendekati 40% ... saat ini lebih dalam kisaran <10%. Apa yang diilustrasikan oleh contoh Anda adalah bahwa pemrogram harus tetap menggunakan bahasa pilihan mereka (dan dari profil Anda jelas bahwa Anda adalah pemrogram C ++ karir). Dalam C # Anda dapat melakukan array 2D int[,]... menindaklanjuti dengan contoh.
nikib3ro
3
Dari apa yang saya tahu, kode dalam contoh C ++ Anda secara harfiah hanya mengalokasikan memori sebelumnya. Implementasi PROPER C # hanya akan menulis 'Daftar <double> arrs = Daftar baru <double> (ROWS * COLS)' yang mengalokasikan memori yang diperlukan untuk mengindeks array 2 dimensi dalam format 1 dimensi (misalnya, apa yang Anda lakukan dalam C ++). Sama sekali tidak ada alasan untuk mengalokasikan array 2 dimensi dan meratakannya secara manual - besarnya iterasi dalam pre-test Anda adalah penyebab kinerja buruk. Saya membayangkan biaya overhead masih akan lebih dalam C #, tetapi tidak dalam jumlah yang cukup besar.
JDSweetBeat
62

Dalam pengalaman saya (dan saya telah banyak bekerja dengan kedua bahasa), masalah utama dengan C # dibandingkan dengan C ++ adalah konsumsi memori yang tinggi, dan saya belum menemukan cara yang baik untuk mengendalikannya. Itu adalah konsumsi memori yang akhirnya akan memperlambat perangkat lunak .NET.

Faktor lain adalah bahwa kompiler JIT tidak dapat menyediakan terlalu banyak waktu untuk melakukan optimasi tingkat lanjut, karena ia berjalan pada saat runtime, dan pengguna akhir akan melihatnya jika membutuhkan terlalu banyak waktu. Di sisi lain, kompiler C ++ memiliki semua waktu yang diperlukan untuk melakukan optimasi pada waktu kompilasi. Faktor ini jauh lebih kecil daripada konsumsi memori, IMHO.

Nemanja Trifunovic
sumber
6
Dalam satu proyek di tempat kerja kami harus menambang sejumlah besar data, termasuk menyimpan banyak GB dalam memori secara bersamaan dan melakukan perhitungan mahal pada semua itu - ini membutuhkan kontrol yang tepat dari semua alokasi, C ++ adalah satu-satunya pilihan. +1 untuk C ++. Di sisi lain, itu hanya satu proyek, kami menghabiskan sebagian besar waktu kami menulis sistem yang berinteraksi dengan simulator lambat, dan debugging bisa menjadi mimpi buruk, jadi saya berharap kami bisa menggunakan bahasa yang mengoptimalkan waktu programmer untuk semua yang lain barang.
Bogatyr
7
@IngeHenriksen: Saya tahu betul pola Buang, tetapi sama sekali tidak membantu dengan memori yang dikelola.
Nemanja Trifunovic
10
@IngeHenriksen membuangnya hanya memastikan bahwa metode Buang telah dipanggil. Pembuangan tidak pernah membebaskan memori yang dikumpulkan sampah. Metode Buang hanya dimaksudkan untuk membersihkan sumber daya yang tidak dikelola seperti pegangan file dan tidak ada hubungannya dengan manajemen memori.
doug65536
1
@NemanjaTrifunovic: "Kompiler JIT tidak mampu terlalu banyak waktu untuk melakukan optimasi lanjutan". Bisakah Anda mengutip beberapa optimasi yang tidak dilakukan oleh JIT karena akan memakan waktu terlalu lama?
Jon Harrop
5
@ user3800527: Sekalipun menambahkan RAM selalu layak (dan tidak - bayangkan Microsoft menambahkan RAM ke setiap pengguna MS Office) yang tidak akan menyelesaikan masalah. Memori bersifat hierarkis dan program C # akan memiliki lebih banyak kesalahan cache daripada program C ++.
Nemanja Trifunovic
35

Satu skenario khusus di mana C ++ masih berada di atas angin (dan akan, untuk tahun-tahun mendatang) terjadi ketika keputusan polimorfik dapat ditentukan sebelumnya pada waktu kompilasi.

Secara umum, enkapsulasi dan pengambilan keputusan yang ditangguhkan adalah hal yang baik karena membuat kode lebih dinamis, lebih mudah untuk beradaptasi dengan perubahan persyaratan dan lebih mudah digunakan sebagai kerangka kerja. Inilah sebabnya mengapa pemrograman berorientasi objek dalam C # sangat produktif dan dapat digeneralisasi dengan istilah “generalisasi”. Sayangnya, generalisasi jenis ini dikenakan biaya saat run-time.

Biasanya, biaya ini tidak substansial tetapi ada aplikasi di mana overhead panggilan metode virtual dan pembuatan objek dapat membuat perbedaan (terutama karena metode virtual mencegah optimasi lainnya seperti inlining panggilan metode). Di sinilah C ++ memiliki keuntungan besar karena Anda dapat menggunakan templat untuk mencapai jenis generalisasi yang berbeda yang tidak memiliki berdampak pada runtime tetapi belum tentu kurang polimorfik daripada OOP. Bahkan, semua mekanisme yang merupakan OOP dapat dimodelkan hanya menggunakan teknik templat dan resolusi waktu kompilasi.

Dalam kasus seperti itu (dan memang, mereka sering terbatas pada domain masalah khusus), C ++ menang melawan C # dan bahasa yang sebanding.

Konrad Rudolph
sumber
6
Sebenarnya, Java VMs (dan mungkin .NET) berusaha keras untuk menghindari pengiriman dinamis. Pada dasarnya, jika ada cara untuk menghindari polymorphims, Anda bisa yakin VM Anda akan melakukannya.
Martin Probst
3
+1 Saya selalu kesulitan menjelaskan hal ini kepada kolega C # saya yang hanya tahu sedikit C ++ dengan cara yang memungkinkan mereka menghargai arti pentingnya. Anda sudah menjelaskannya dengan cukup baik.
Roman Starkov
9
@ crtracy: Anda membuat taruhan tanpa aplikasi komputasi kinerja tinggi. Pertimbangkan ramalan cuaca, bioinformatika, dan simulasi numerik. Prospek kinerja C ++ di area ini tidak akan menyusut, karena tidak ada kode lain yang dapat mencapai kinerja yang sebanding pada tingkat abstraksi tinggi yang sama.
Konrad Rudolph
5
@Jon Apel dan jeruk. Klaim khusus Anda adalah "C # adalah urutan besarnya lebih cepat dari C ++ dalam konteks metaprogramming", bukan "menggunakan kode prakompilasi adalah pesanan besarnya lebih cepat dari kode yang ditafsirkan". Sementara kami melakukannya, klaim Anda bahwa pembuatan kode runtime adalah "lebih umum" daripada pembuatan kode waktu kompilasi juga jelas salah - mereka berdua memiliki kekuatan dan kelemahan. Pembuatan kode waktu kompilasi menggunakan sistem tipe untuk memberikan keamanan tipe statis - Pembuatan kode runtime tidak dapat melakukan itu ( dapat memberikan keamanan tipe yang kuat, tetapi tidak untuk keselamatan tipe statis ).
Konrad Rudolph
5
@ user3800527 Saya pikir Anda kehilangan inti dari jawaban ini. Tentu saja Anda dapat mengatasi ini dengan memecahkan enkapsulasi dan menjatuhkannya ke struktur tingkat rendah - Anda dapat menulis assembly dalam (sebagian besar) bahasa apa pun. Hal yang membuat C ++ (hampir) unik, dan secara unik cocok untuk pemrograman berkinerja tinggi, adalah Anda dapat membangun abstraksi tingkat tinggi yang datang tanpa biaya runtime. Jadi, Anda tidak perlu menulis kode seperti perakitan di C ++ untuk mendapatkan kinerja premium: yang ditulis dengan baik sort(arr, generic_comparer)akan seefisien loop tulisan tangan di C ++. Itu tidak akan pernah dalam C #.
Konrad Rudolph
20

C ++ (atau C dalam hal ini) memberi Anda kendali atas struktur data Anda. Jika Anda ingin bermain-main, Anda memiliki opsi itu. Aplikasi Java atau .NET yang dikelola besar (OWB, Visual Studio 2005 ) yang menggunakan struktur data internal perpustakaan Java / .NET membawa bagasi. Saya telah melihat sesi desainer OWB menggunakan lebih dari 400 MB RAM dan BIDS untuk desain kubus atau ETL masuk ke 100-an MB juga.

Pada beban kerja yang dapat diprediksi (seperti kebanyakan tolok ukur yang mengulangi proses berkali-kali) JIT dapat memberi Anda kode yang dioptimalkan dengan cukup baik sehingga tidak ada perbedaan praktis.

IMO pada aplikasi besar perbedaannya tidak begitu banyak JIT seperti struktur data yang menggunakan kode itu sendiri. Di mana suatu aplikasi adalah memori-berat Anda akan mendapatkan penggunaan cache yang kurang efisien. Kehilangan cache pada CPU modern cukup mahal. Di mana C atau C ++ benar-benar menang adalah di mana Anda dapat mengoptimalkan penggunaan struktur data untuk bermain dengan baik dengan cache CPU.

ConcernedOfTunbridgeWells
sumber
19

Untuk grafik, kelas C # Graphics standar jauh lebih lambat daripada GDI yang diakses melalui C / C ++. Saya tahu ini tidak ada hubungannya dengan bahasa per se, lebih dengan total. NET platform, tetapi Grafik adalah apa yang ditawarkan kepada pengembang sebagai pengganti GDI, dan kinerjanya sangat buruk saya bahkan tidak berani melakukan grafik dengan itu.

Kami memiliki tolok ukur sederhana yang kami gunakan untuk melihat seberapa cepat perpustakaan grafis, dan itu hanya menggambar garis acak di jendela. C ++ / GDI masih tajam dengan 10.000 baris sementara C # / Grafik mengalami kesulitan melakukan 1000 secara real-time.

QBziZ
sumber
5
Saya tertarik dengan jawaban Anda. Sudahkah Anda menguji tolok ukur yang sama dengan kode dan kunci tidak aman, dan menggambar garis acak sendiri? Nah, itu akan menjadi hal yang menarik untuk dilihat.
Pedery
2
@Pedery nggak saya belum. hanya menggunakan GDI dan .NET.Graphics dengan cara yang paling dasar. apa yang Anda maksud dengan "menggambar garis acak sendiri"?
QBziZ
1
Maka Anda mungkin harus mempertimbangkan untuk menguji ini untuk mendapatkan metrik yang lebih realistis untuk seberapa cepat C # bisa. Berikut adalah ikhtisar teknik yang bagus: bobpowell.net/lockingbits.htm
Pedery
6
Bukan itu yang ingin kami lakukan, menempatkan piksel terpisah di dalam bingkai. Jika Anda harus mengimplementasikan semuanya sendiri, apa gunanya menentang API / Platform untuk dikodekan? Bagi saya ini bukan argumen. Kami tidak pernah perlu untuk menempatkan piksel terpisah dalam framebuffer di GDI untuk menggambar garis, dan kami tidak berencana untuk melakukan ini dalam. NET juga. Dalam pandangan saya, kami memang menggunakan metrik realistis, dan .NET ternyata lambat.
QBziZ
1
Yah, saya hanya punya sedikit ide apa deteksi gumpalan, tetapi hanya menyatakan satu waktu tidak membuktikan apa-apa sama sekali. Sudahkah Anda menulis satu di C ++? Dalam JavaScript? Dan membandingkannya dengan yang ada di C #? Dan selain itu, saya tidak berpikir deteksi gumpalan menggunakan banyak grafis primitif. Koreksi saya jika salah, tetapi saya rasa ini adalah algoritma statistik yang melakukan operasi pada piksel.
QBziZ
13

Pengumpulan sampah adalah alasan utama Java # CANNOT digunakan untuk sistem waktu-nyata.

  1. Kapan GC akan terjadi?

  2. Itu akan makan waktu berapa lama?

Ini tidak menentukan.


sumber
5
Saya bukan penggemar Java besar tetapi tidak ada yang mengatakan Java tidak dapat menggunakan GC ramah real-time.
Zan Lynx
5
Ada banyak implementasi GC waktu nyata jika Anda ingin melihatnya. (GC adalah daerah yang dipenuhi dengan makalah penelitian)
Arafangion
FWIW, Richard Jones baru saja menerbitkan versi terbaru dari buku pengumpulan sampahnya yang mencakup, antara lain, desain GC real-time yang canggih.
Jon Harrop
11
Ini adalah argumen yang tidak masuk akal, Windows (dan Linux) bukan OS Waktu Nyata. Kode C ++ Anda dapat diganti untuk sejumlah slot 18 ms kapan pun juga.
Henk Holterman
2
@HenkHolterman Benar, tetapi Anda selalu bisa menulis boot-loader dalam rakitan, ikat itu ke dalam bootstrap kernel untuk aplikasi Anda dan jalankan aplikasi C ++ secara langsung terhadap perangkat keras (dalam RTWt). Anda tidak dapat melakukan ini dalam C # dan upaya apa pun yang saya lihat hanya meniru perakitan pra-dikompilasi dalam C # dan menggunakan satu ton kode C, yang membuatnya kurang point untuk menggunakan C #. Membaca semua ini agak lucu, karena C # benar-benar tidak berguna tanpa kerangka NET.
zackery.fix
11

Kami harus menentukan apakah C # sebanding dengan C ++ dalam kinerja dan saya menulis beberapa program pengujian untuk itu (menggunakan Visual Studio 2005 untuk kedua bahasa). Ternyata tanpa pengumpulan sampah dan hanya mempertimbangkan bahasa (bukan kerangka kerja) C # pada dasarnya memiliki kinerja yang sama dengan C ++. Alokasi memori jauh lebih cepat di C # daripada di C ++ dan C # memiliki sedikit keunggulan dalam determinisme ketika ukuran data meningkat di luar batas garis cache. Namun, semua ini akhirnya harus dibayar dan ada biaya besar dalam bentuk hit kinerja non-deterministik untuk C # karena pengumpulan sampah.

ILoveFortran
sumber
1
Di C ++, Anda memiliki opsi untuk menggunakan metode alokasi yang berbeda, jadi tergantung pada bagaimana memori dialokasikan (AOT?) Di C #, itu bisa dilakukan dengan cara yang sama (tapi jauh lebih cepat) di C ++.
zackery.fix
5
@ zackery.fix .NET memiliki kelebihan yang menarik dalam alokasi heap, karena hanya perlu memindahkan pointer untuk mengalokasikan objek baru. Ini hanya layak karena pengumpul sampah pemadatan. Tentu saja Anda dapat melakukan hal yang sama di C ++, tetapi C ++ tidak melakukan itu. Sangat lucu bagaimana Anda menggunakan argumen yang sama untuk mengatakan "C # bisa tetapi tidak, jadi ini sampah" dan "C ++ tidak, tetapi bisa, jadi itu luar biasa" :)
Luaan
9

Seperti biasa, itu tergantung aplikasi. Ada kasus di mana C # mungkin diabaikan lebih lambat, dan kasus lain di mana C ++ adalah 5 atau 10 kali lebih cepat, terutama dalam kasus di mana operasi dapat dengan mudah dilakukan dengan SIMD.

Shikari Gelap
sumber
Kasus terbaik untuk VMs adalah kompilasi run-time dari kode yang dihasilkan (misalnya untuk mencocokkan ekspresi reguler yang dibaca pada saat run time) karena program vanilla C ++ yang dikompilasi secara statis hanya dapat menggunakan interpretasi karena mereka tidak memiliki kompiler JIT bawaan.
Jon Harrop
Catatan dari masa depan: .NET memang memiliki dukungan untuk SIMD dan teman-teman sejak sekitar 2014, meskipun tidak banyak digunakan.
Luaan
9

Saya tahu itu bukan apa yang Anda minta, tetapi C # seringkali lebih cepat untuk ditulis daripada C ++, yang merupakan bonus besar dalam pengaturan komersial.

Kramii
sumber
2
Saya akan mengatakan itu lebih cepat sebagian besar waktu :)
Trap
8

C / C ++ dapat melakukan jauh lebih baik dalam program-program di mana ada array besar atau perulangan berat / iterasi atas array (ukuran apa pun). Ini adalah alasan bahwa grafik umumnya jauh lebih cepat di C / C ++, karena operasi array yang berat mendasari hampir semua operasi grafis. NET dikenal sangat lambat dalam operasi pengindeksan array karena semua pemeriksaan keamanan, dan ini terutama berlaku untuk array multi-dimensi (dan, ya, array C # persegi panjang bahkan lebih lambat daripada array C # bergerigi).

Bonus C / C ++ paling jelas jika Anda tetap menggunakan pointer dan menghindari Boost, std::vectordan wadah tingkat tinggi lainnya, serta inlinesetiap fungsi kecil yang mungkin. Gunakan array old-school jika memungkinkan. Ya, Anda akan membutuhkan lebih banyak baris kode untuk mencapai hal yang sama dengan yang Anda lakukan di Java atau C # saat Anda menghindari kontainer tingkat tinggi. Jika Anda membutuhkan array berukuran dinamis, Anda hanya perlu ingat untuk memasangkan Anda new T[]dengan yang sesuaidelete[] pernyataan (atau gunakanstd::unique_ptr) - harga untuk kecepatan ekstra adalah Anda harus kode lebih hati-hati. Tetapi sebagai gantinya, Anda bisa membebaskan diri Anda sendiri dari overhead memori yang dikelola / pengumpul sampah, yang dapat dengan mudah 20% atau lebih dari waktu pelaksanaan program berorientasi objek baik di Jawa dan .NET, serta yang dikelola secara besar-besaran biaya pengindeksan array memori. Aplikasi C ++ juga dapat mengambil manfaat dari beberapa sakelar kompiler yang bagus dalam kasus tertentu tertentu.

Saya seorang programmer ahli dalam C, C ++, Java, dan C #. Baru-baru ini saya memiliki kesempatan langka untuk mengimplementasikan program algoritmik yang sama persis dalam 3 bahasa terakhir. Program ini memiliki banyak operasi array matematika dan multi-dimensi. Saya sangat mengoptimalkan ini dalam semua 3 bahasa. Hasilnya khas dari apa yang biasanya saya lihat dalam perbandingan yang kurang ketat: Java sekitar 1.3x lebih cepat dari C # (sebagian besar JVM lebih dioptimalkan daripada CLR), dan versi raw pointer C ++ datang sekitar 2.1x lebih cepat daripada C #. Perhatikan bahwa program C # hanya menggunakan kode aman — menurut pendapat saya Anda sebaiknya menuliskannya dalam C ++ sebelum menggunakan unsafekata kunci.

Supaya tidak ada yang berpikir saya memiliki sesuatu terhadap C #, saya akan menutup dengan mengatakan bahwa C # mungkin adalah bahasa favorit saya. Ini adalah bahasa pengembangan yang paling logis, intuitif dan cepat yang saya temui sejauh ini. Saya melakukan semua prototipe saya di C #. Bahasa C # memiliki banyak keunggulan kecil dan halus di atas Java (ya, saya tahu Microsoft memiliki kesempatan untuk memperbaiki banyak kekurangan Java dengan memasukkan game terlambat dan bisa juga menyalin Java). Bersulang untuk Calendarkelas Java siapa pun? Jika Microsoft pernah mengeluarkan upaya nyata untuk mengoptimalkan CLR dan .NET JITter, C # dapat dengan serius mengambil alih. Saya benar-benar terkejut mereka belum melakukannya — mereka melakukan banyak hal dengan benar dalam bahasa C #, mengapa tidak menindaklanjutinya dengan optimisasi kompiler yang sangat memukul? Mungkin jika kita semua memohon.

Saus spesial
sumber
3
"Anda hanya perlu ingat untuk memasangkan Anda new T[]dengan yang sesuai delete[]" - Tidak, Anda tidak. Ada yang std::unique_ptrharus dilakukan untukmu.
emlai
dengan asumsi Anda menulis sesuatu dalam grafik mengapa menulis kode aman di c #, sudahkah Anda mempertimbangkan untuk menggunakan kode tidak aman dan membandingkan lagi?
user3800527
7

> Dari apa yang saya dengar ...

Kesulitan Anda tampaknya dalam memutuskan apakah apa yang Anda dengar kredibel, dan kesulitan itu hanya akan terulang ketika Anda mencoba menilai balasan di situs ini.

Bagaimana Anda akan memutuskan apakah hal-hal yang orang katakan di sini lebih atau kurang kredibel daripada apa yang Anda dengar sebelumnya?

Salah satu caranya adalah dengan meminta bukti .

Ketika seseorang mengklaim "ada beberapa area di mana C # terbukti lebih cepat daripada C ++" tanyakan kepada mereka mengapa mereka mengatakan itu , minta mereka menunjukkan pengukuran kepada Anda, minta mereka untuk menunjukkan kepada Anda program. Terkadang mereka hanya melakukan kesalahan. Kadang-kadang Anda akan menemukan bahwa mereka hanya mengekspresikan pendapat daripada membagikan sesuatu yang mereka anggap benar.

Seringkali informasi dan pendapat akan campur aduk dalam apa yang diklaim orang, dan Anda harus mencoba dan memilah mana. Misalnya, dari balasan di forum ini:

  • "Ambil patokan di http://shootout.alioth.debian.org/ dengan banyak skeptis, karena ini sebagian besar menguji kode aritmatika, yang kemungkinan besar tidak mirip dengan kode Anda sama sekali."

    Tanyakan pada diri Anda apakah Anda benar-benar mengerti apa "kode aritmatika yang sebagian besar menguji" ini , dan kemudian tanyakan pada diri Anda apakah penulis telah benar-benar menunjukkan kepada Anda bahwa klaimnya benar.

  • "Itu adalah tes yang agak tidak berguna, karena itu benar-benar tergantung pada seberapa baik masing-masing program telah dioptimalkan; Saya telah berhasil mempercepat beberapa dari mereka dengan 4-6 kali atau lebih, menjadikannya jelas bahwa perbandingan antara program yang tidak dioptimalkan agak bodoh."

    Tanyakan pada diri Anda apakah penulis telah benar-benar menunjukkan kepada Anda bahwa ia berhasil "mempercepat beberapa dari mereka dengan 4-6 kali atau lebih" - itu adalah klaim yang mudah dibuat!

Peter Mortensen
sumber
Saya sangat setuju dengan Anda dan itulah alasan mengapa saya bertanya di forum ini ... Lagipula, jawabannya harus ada di suatu tempat, bukan? :)
Trap
1
Iya. Jawabannya adalah, tergantung.".
user49117
6

Untuk masalah 'paralel memalukan', ketika menggunakan Intel TBB dan OpenMP pada C ++ saya telah mengamati peningkatan kinerja sekitar 10x dibandingkan dengan masalah (matematika murni) serupa yang dilakukan dengan C # dan TPL. SIMD adalah salah satu area di mana C # tidak dapat bersaing, tetapi saya juga mendapat kesan bahwa TPL memiliki overhead yang cukup besar.

Yang mengatakan, saya hanya menggunakan C ++ untuk tugas-tugas penting di mana saya tahu saya akan dapat melakukan multithread dan mendapatkan hasil dengan cepat. Untuk yang lainnya, C # (dan kadang-kadang F #) baik-baik saja.

Dmitri Nesteruk
sumber
5

Ini adalah pertanyaan yang sangat samar tanpa jawaban pasti yang nyata.

Sebagai contoh; Saya lebih suka memainkan game 3D yang dibuat di C ++ daripada di C #, karena kinerjanya tentu jauh lebih baik. (Dan saya tahu XNA, dll., Tetapi tidak mendekati hal yang sebenarnya).

Di sisi lain, seperti yang disebutkan sebelumnya; Anda harus mengembangkan dalam bahasa yang memungkinkan Anda melakukan apa yang Anda inginkan dengan cepat, dan jika perlu optimalkan.

David The Man
sumber
4
Bisakah Anda menyebutkan beberapa contoh? Game yang ditulis dalam bahasa C # apa yang menurut Anda lambat
Karl
1
Bahkan contoh aplikasi yang datang dengan instalasi terasa lambat.
David The Man
9
Pengumpul sampah adalah tanggung jawab besar dalam membuat game dengan C #, karena dapat menendang kapan saja, menyebabkan jeda besar. Manajemen memori eksplisit menjadi lebih mudah untuk pengembangan game.
postfuturist
3
Sebagian besar game modern terbatas pada GPU. Untuk permainan seperti itu tidak masalah jika logika (dijalankan pada CPU) lebih lambat 10%, mereka masih dibatasi oleh GPU, bukan CPU. Pengumpul sampah adalah masalah nyata, menyebabkan pembekuan acak pendek jika alokasi memori tidak disetel dengan baik.
Michael Entin
2
@postfuturist: Itu tidak benar di PC; pengumpul sampah melakukan pekerjaan yang baik untuk masuk dan keluar saya tidak pernah mengalami masalah dengan itu. Namun, pada Xbox 360 dan Zune / Windows-7-Phone, pengumpul sampah tidak hampir sepandai pada PC; Saya juga tidak pernah menulis, tetapi orang-orang yang memberi tahu saya pengumpul sampah adalah masalah besar .
BlueRaja - Danny Pflughoeft
5

Bahasa .NET dapat secepat kode C ++, atau bahkan lebih cepat, tetapi kode C ++ akan memiliki throughput yang lebih konstan karena .NET runtime harus berhenti sebentar untuk GC , bahkan jika itu sangat pintar tentang jeda-nya.

Jadi, jika Anda memiliki beberapa kode yang harus berjalan cepat secara konsisten tanpa jeda, .NET akan memperkenalkan latensi di beberapa titik , bahkan jika Anda sangat berhati-hati dengan runtime GC.

Florian Doyon
sumber
6
-1: Ini sebenarnya mitos. Pertama, latensi C ++ idiomatik sebenarnya mengerikan dan seringkali jauh lebih buruk daripada .NET karena RAII menyebabkan longsoran destruktor ketika struktur data besar jatuh di luar ruang lingkup sedangkan GC modern bersifat inkremental dan .NET bahkan bersamaan. Kedua, Anda dapat benar-benar menghapus GC jeda di .NET dengan tidak mengalokasikan.
Jon Harrop
2
Jika Anda melakukan ini, maka Anda harus melepaskan BCL karena sebagian besar metode membuat objek sementara.
Florian Doyon
5
Ini cukup benar, tidak sampai .net 4 bahwa GC dibuat tambahan. Kami memiliki aplikasi C # besar yang berhenti sebentar untuk GC. Untuk aplikasi kritis kinerja, ini adalah pembunuh.
Justin
5
Ada alasan mengapa program yang cenderung mendorong perangkat keras cenderung menggunakan C ++. Anda memiliki kontrol yang lebih baik saat Anda membutuhkannya. Kinerja hanya kunci ketika Anda mendorong sistem, jika tidak gunakan C # atau Java untuk menghemat waktu Anda.
VoronoiPotato
4
jika Anda tidak dapat mengelola perilaku cache, Anda tidak dapat mengalahkan kode c ++ yang dioptimalkan. Kehilangan cache dari L1 ke memori utama dapat memperlambat operasi Anda 100 kali.
DAG
4

Secara teori, untuk aplikasi tipe server yang berjalan lama, bahasa yang dikompilasi JIT bisa menjadi banyak lebih cepat daripada rekan yang dikompilasi secara asli. Karena bahasa yang dikompilasi JIT umumnya pertama kali dikompilasi ke bahasa perantara tingkat yang cukup rendah, Anda dapat melakukan banyak optimasi tingkat tinggi tepat pada waktu kompilasi. Keuntungan besar datang bahwa JIT dapat terus mengkompilasi ulang bagian kode dengan cepat karena semakin banyak data tentang bagaimana aplikasi sedang digunakan. Itu dapat mengatur jalur kode yang paling umum untuk memungkinkan prediksi cabang berhasil sesering mungkin. Itu dapat mengatur ulang blok kode terpisah yang sering dipanggil bersama untuk menyimpan keduanya di cache. Ini dapat menghabiskan lebih banyak upaya mengoptimalkan loop batin.

Saya ragu bahwa ini dilakukan oleh .NET atau salah satu JRE, tetapi sedang diteliti kembali ketika saya masih di universitas, jadi itu tidak masuk akal untuk berpikir bahwa hal-hal semacam ini dapat menemukan jalan mereka ke dunia nyata di beberapa titik segera .

Gerhana
sumber
4

Aplikasi yang membutuhkan akses memori intensif misalnya. manipulasi gambar biasanya lebih baik ditulis dalam lingkungan yang tidak dikelola (C ++) daripada yang dikelola (C #). Loop batin yang dioptimalkan dengan pointer arithmetics jauh lebih mudah dikendalikan di C ++. Dalam C # Anda mungkin perlu menggunakan kode yang tidak aman untuk mendekati kinerja yang sama.

Kalle
sumber
4

Saya telah menguji vectordi C ++ dan C # setara - Listdan array 2d sederhana.

Saya menggunakan edisi Visual C # / C ++ 2010 Express. Kedua proyek tersebut adalah aplikasi konsol sederhana, saya telah mengujinya dalam mode pelepasan dan debug standar (tanpa pengaturan khusus). Daftar C # berjalan lebih cepat di pc saya, inisialisasi array juga lebih cepat di C #, operasi matematika lebih lambat.

Saya menggunakan Intel Core2Duo [email protected], C # - .NET 4.0.

Saya tahu bahwa implementasi vektor berbeda dari daftar C #, tetapi saya hanya ingin menguji koleksi yang akan saya gunakan untuk menyimpan objek saya (dan dapat menggunakan indeks accessor).

Tentu saja Anda perlu mengosongkan memori (katakanlah untuk setiap penggunaan new), tapi saya ingin menjaga kode tetap sederhana.

Tes C ++ vektor :

static void TestVector()
{
    clock_t start,finish;
    start=clock();
    vector<vector<double>> myList=vector<vector<double>>();
    int i=0;
    for( i=0; i<500; i++)
    {
        myList.push_back(vector<double>());
        for(int j=0;j<50000;j++)
            myList[i].push_back(j+i);
    }
    finish=clock();
    cout<<(finish-start)<<endl;
    cout<<(double(finish - start)/CLOCKS_PER_SEC);
}

Tes daftar C #:

private static void TestVector()
{

    DateTime t1 = System.DateTime.Now;
    List<List<double>> myList = new List<List<double>>();
    int i = 0;
    for (i = 0; i < 500; i++)
    {
        myList.Add(new List<double>());
        for (int j = 0; j < 50000; j++)
            myList[i].Add(j *i);
    }
    DateTime t2 = System.DateTime.Now;
    Console.WriteLine(t2 - t1);
}

C ++ - array:

static void TestArray()
{
    cout << "Normal array test:" << endl;
    const int rows = 5000;
    const int columns = 9000;
    clock_t start, finish;

    start = clock();
    double** arr = new double*[rows];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    finish = clock();

    cout << (finish - start) << endl;

    start = clock();
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    finish = clock();

    cout << (finish - start) << endl;
}

C # - array:

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

}

Waktu: (Rilis / Debug)

C ++

  • 600/606 ms array init,
  • Isi array 200/270 ms,
  • 1sec / 13sec vektor init & isi.

(Ya, 13 detik, saya selalu memiliki masalah dengan daftar / vektor dalam mode debug.)

C #:

  • 20/20 ms array init,
  • Isi array 403/440 ms,
  • 710/742 ms daftar init & fill.
Wiory
sumber
1
Saya ingin melihat pengakses indeks di std :: list. Bagaimanapun, dibutuhkan 37 detik dengan daftar, mode rilis. Rilis tanpa debugging: daftar 3s, vektor 0,3 dtk. Mungkin masalah dereferensi atau sth. Contoh: nopaste.pl/12fb
Wiory
2
Untuk pengukuran yang lebih tepat, Anda seharusnya tidak menggunakan System.DateTime.Now, melainkan, kelas Stopwatch .
Sam
4
Salah satu alasan Anda mendapatkan waktu isian lambat untuk vektor di C ++ adalah Anda menggunakan push_back. Ini telah ditunjukkan pada banyak posting menjadi lebih lambat daripada menggunakan metode at atau operator []. Untuk menggunakan salah satu metode tersebut, Anda perlu menggunakan metode mengubah ukuran atau cadangan. Selain itu, alasan inisialisasi Anda terlalu lama untuk c ++ vector case adalah karena Anda memaksa copy atau operator penugasan [tidak yakin yang mana dalam kasus ini) untuk menginisialisasi vektor c ++ Anda. Untuk array di c ++ ada algoritma yang menggunakan 2 panggilan baru daripada 5001 dan lebih cepat iterasi juga.
Zachary Kraus
5
Saya pikir Anda tidak melakukan c ++ dengan cara yang tepat. Hanya sekilas dan menemukan begitu banyak masalah. Misalnya vektor <vektor <double>> myList = vektor <vektor <double>> ()
DAG
2
Wow. Tidak yakin kesimpulan apa yang dapat diambil dari membandingkan Daftar versus array yang dapat diubah ukurannya, tetapi jika Anda akan menggunakan vektor seperti ini, Anda ingin mempelajari tentang cadangan (), teman saya, cadangan ().
U007D
3

Yah, itu tergantung. Jika byte-code diterjemahkan ke dalam mesin-code (dan bukan hanya JIT) (maksud saya jika Anda menjalankan program) dan jika program Anda menggunakan banyak alokasi / deallocations itu bisa lebih cepat karena algoritma GC hanya perlu satu pass (secara teoritis) melalui seluruh memori sekali, tetapi panggilan malloc / realloc / free C / C ++ normal menyebabkan overhead pada setiap panggilan (call-overhead, overhead struktur data, cache misses;)).

Jadi secara teori dimungkinkan (juga untuk bahasa GC lainnya).

Saya tidak benar-benar melihat kelemahan ekstrim dari tidak dapat menggunakan metaprogramming dengan C # untuk sebagian besar aplikasi, karena kebanyakan programmer tidak menggunakannya.

Keuntungan besar lainnya adalah bahwa SQL, seperti "ekstensi" LINQ , memberikan peluang bagi kompiler untuk mengoptimalkan panggilan ke basis data (dengan kata lain, kompiler dapat mengkompilasi seluruh LINQ ke satu "gumpalan" biner di mana fungsi yang dipanggil digariskan atau untuk penggunaan Anda dioptimalkan, tapi saya berspekulasi di sini).

Quonux
sumber
1
Pengembang C ++ yang tepat tidak akan mengalami masalah yang Anda jelaskan. Hanya programmer C yang buruk yang memutuskan untuk menampar kelas pada program mereka dan menyebutnya C ++ yang memiliki masalah tersebut.
jelas
1
demi cinta para dewa, ini berumur 8 tahun, OMFGz
Quonux
jangan ragu untuk memberikan jawaban yang lebih baik dan terkini
Quonux
2

Saya kira ada aplikasi yang ditulis dalam C # berjalan cepat, serta ada lebih banyak aplikasi C ++ tertulis berjalan cepat (baik C ++ hanya lebih tua ... dan mengambil UNIX juga ...)
- pertanyaannya adalah - apa itu, pengguna dan pengembang mengeluh tentang ... Untuk menulis kode dalam C # sangat sederhana dan cepat (jangan lupa itu juga meningkatkan kemungkinan kesalahan. Dalam kasus C ++, pengembang mengeluh kebocoran memori, - berarti penghancuran, panggilan antara DLL, serta "DLL hell" - masalah dengan dukungan dan penggantian perpustakaan dengan yang lebih baru ... Saya rasa lebih banyak keterampilan yang Anda miliki dalam bahasa pemrograman, semakin banyak kualitas (dan kecepatan) yang menjadi ciri perangkat lunak Anda.
Nah, IMHO, dalam kasus C # kami memiliki UI yang sangat nyaman, hierarki perpustakaan yang sangat bagus, dan seluruh sistem antarmuka CLI. Dalam kasus C ++ kami memiliki template, ATL, COM, MFC dan seluruh kode yang sudah ditulis dan menjalankan kode seperti OpenGL, DirectX dan sebagainya ... Pengembang mengeluh panggilan GC yang meningkat secara tidak pasti dalam kasus C # (berarti program berjalan cepat, dan dalam satu detik - bang! ini macet).

bgee
sumber
2

Saya akan begini: programmer yang menulis kode lebih cepat, adalah orang-orang yang lebih mengetahui apa yang membuat mesin saat ini berjalan cepat, dan kebetulan mereka juga orang-orang yang menggunakan alat yang tepat yang memungkinkan tingkat rendah yang tepat dan deterministik teknik optimasi. Untuk alasan ini, orang-orang ini adalah orang-orang yang menggunakan C / C ++ daripada C #. Saya akan mengatakan hal ini sebagai fakta.

Johan Boulé
sumber
Notch kode minecraft menjadi sangat cepat mengingat jumlah data yang dia manipulasi. Juga, ia mengkodekannya sebagian besar sendirian dalam jumlah waktu yang relatif singkat, sesuatu yang hampir mustahil di C ++. Saya setuju dengan teknik optimasi - jika Anda memiliki waktu dev 10x ekstra untuk menghabiskan sehingga kode Anda berjalan dua kali lebih cepat, mungkin layak.
Bill K
2

Jika saya tidak salah, template C # ditentukan saat runtime. Ini harus lebih lambat dari kompilasi templat waktu C ++.

Dan ketika Anda menerima semua optimasi waktu kompilasi lainnya yang disebutkan oleh begitu banyak orang lain, serta kurangnya keamanan yang memang, berarti, lebih cepat ...

Saya akan mengatakan C ++ adalah pilihan yang jelas dalam hal kecepatan mentah dan konsumsi memori minimum. Tetapi ini juga berarti lebih banyak waktu mengembangkan kode dan memastikan Anda tidak membocorkan memori atau menyebabkan pengecualian null pointer.

Putusan:

  • C #: Pengembangan lebih cepat, lari lebih lambat

  • C ++: Pengembangan lambat, lari lebih cepat.

HumbleWebDev
sumber
1

Itu benar-benar tergantung pada apa yang ingin Anda capai dalam kode Anda. Saya pernah mendengar bahwa itu hanya legenda urban bahwa ada perbedaan kinerja antara VB.NET, C # dan C ++ yang dikelola. Namun, saya telah menemukan, setidaknya dalam perbandingan string, yang berhasil C ++ mengalahkan celana dari C #, yang pada gilirannya mengalahkan celana dari VB.NET.

Saya tidak pernah melakukan perbandingan lengkap dalam kompleksitas algoritmik antara bahasa. Saya juga hanya menggunakan pengaturan default di masing-masing bahasa. Di VB.NET saya menggunakan pengaturan untuk meminta deklarasi variabel, dll. Berikut adalah kode yang saya gunakan untuk C ++ terkelola: (Seperti yang Anda lihat, kode ini cukup sederhana). Saya menjalankan hal yang sama dalam bahasa lain di Visual Studio 2013 dengan .NET 4.6.2.

#include "stdafx.h"

using namespace System;
using namespace System::Diagnostics;

bool EqualMe(String^ first, String^ second)
{
    return first->Equals(second);
}
int main(array<String ^> ^args)
{
    Stopwatch^ sw = gcnew Stopwatch();
    sw->Start();
    for (int i = 0; i < 100000; i++)
    {
        EqualMe(L"one", L"two");
    }
    sw->Stop();
    Console::WriteLine(sw->ElapsedTicks);
    return 0;
}
Charles Owen
sumber
1

Ada beberapa perbedaan utama antara C # dan C ++ pada aspek kinerja:

  • C # berbasis GC / heap. Alokasi dan GC itu sendiri adalah overhead sebagai bukan lokalitas dari akses memori
  • Pengoptimal C ++ telah menjadi sangat baik selama bertahun-tahun. Kompiler JIT tidak dapat mencapai level yang sama karena mereka hanya memiliki waktu kompilasi terbatas dan tidak melihat lingkup global

Selain itu kompetensi programmer juga berperan. Saya telah melihat kode C ++ yang buruk di mana kelas mana dilewatkan oleh nilai sebagai argumen di semua tempat. Anda benar-benar dapat membuat kinerja lebih buruk di C ++ jika Anda tidak tahu apa yang Anda lakukan.

gast128
sumber
0

> Bagaimanapun juga, jawabannya harus ada di suatu tempat, bukan? :)

Umm, tidak.

Seperti yang dicatat beberapa balasan, pertanyaan tersebut tidak ditentukan dengan cara yang mengundang pertanyaan sebagai jawaban, bukan jawaban. Untuk mengambil hanya satu cara:

Lalu program apa? Mesin yang mana? OS yang mana? Kumpulan data yang mana?

Peter Mortensen
sumber
Saya sangat setuju. Saya bertanya-tanya mengapa orang mengharapkan jawaban yang tepat (63,5%), ketika mereka mengajukan pertanyaan umum. Saya kira tidak ada jawaban umum untuk pertanyaan seperti ini.
panggil aku Steve
@callmesteve: Saya tahu apa yang Anda maksudkan, tetapi kalimat terakhir Anda seharusnya terdengar seperti paku di papan tulis untuk programmer mana pun.
Wouter van Nifterick
1
Ini tampaknya tidak menjawab pertanyaan, dan lebih banyak membaca sebagai komentar atau kata-kata kasar.
Tas
-13

Terinspirasi oleh ini, saya melakukan tes cepat dengan 60 persen instruksi umum yang dibutuhkan di sebagian besar program.

Berikut kode C #:

for (int i=0; i<1000; i++)
{
    StreamReader str = new StreamReader("file.csv");
    StreamWriter stw = new StreamWriter("examp.csv");
    string strL = "";
    while((strL = str.ReadLine()) != null)
    {
        ArrayList al = new ArrayList();
        string[] strline = strL.Split(',');
        al.AddRange(strline);
        foreach(string str1 in strline)
        {
            stw.Write(str1 + ",");
        }
        stw.Write("\n");
    }
    str.Close();
    stw.Close();
}

Array string dan arraylist digunakan dengan sengaja untuk memasukkan instruksi tersebut.

Berikut kode c ++:

for (int i = 0; i<1000; i++)
{
    std::fstream file("file.csv", ios::in);
    if (!file.is_open())
    {
        std::cout << "File not found!\n";
        return 1;
    }

    ofstream myfile;
    myfile.open ("example.txt");
    std::string csvLine;

    while (std::getline(file, csvLine))
    {
        std::istringstream csvStream(csvLine);
        std::vector csvColumn;
        std::string csvElement;

        while( std::getline(csvStream, csvElement, ‘,’) )
        {
            csvColumn.push_back(csvElement);
        }

        for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
        {
            myfile << *j << ", ";
        }

        csvColumn.clear();
        csvElement.clear();
        csvLine.clear();
        myfile << "\n";
    }
    myfile.close();
    file.close();
}

Ukuran file input yang saya gunakan adalah 40 KB.

Dan inilah hasilnya -

  • Kode C ++ dijalankan dalam 9 detik.
  • Kode C #: 4 detik !!!

Oh, tapi ini di Linux ... Dengan C # berjalan di Mono ... Dan C ++ dengan g ++.

OK, inilah yang saya dapatkan di Windows - Visual Studio 2003 :

  • Kode C # dijalankan dalam 9 detik.
  • Kode C ++ - 370 detik yang mengerikan !!!
rks
sumber
7
Anda menggunakan struktur data dan kode pustaka yang berbeda di sana, meskipun "370 detik" menunjukkan sesuatu yang mengerikan - Anda tidak menjalankannya di debugger, bukan? Saya menduga bahwa kinerja perpustakaan CSV yang Anda gunakan lebih menarik daripada kinerja bahasa yang Anda gunakan. Saya akan mempertanyakan penggunaan vektor dalam konteks itu, dan optimisasi apa yang Anda gunakan. Selain itu, secara luas diketahui bahwa iostreams (khususnya, "myfile << * j <<", ";") jauh lebih lambat daripada metode penulisan file lainnya, setidaknya untuk beberapa implementasi umum.
Arafangion
6
Akhirnya, Anda melakukan lebih banyak pekerjaan dalam versi C ++. (Mengapa Anda membersihkan csvColumn, csvElement dan csvLines?)
Arafangion
2
Setiap iterasi dari loop sementara akan merusak dan merekonstruksi string std :: istream dan std :: vektor dan std ::. Tubuh sementara keluar dari ruang lingkup setiap iterasi, semua variabel di dalam ruang sementara akan merusak dan membangun pada setiap iterasi.
doug65536
1
dari tampilan membaca kode c ++ Anda mencoba menyalin dari satu file ke file lain. Alih-alih menggunakan interaksi kompleks antara aliran file, string, vektor, dan aliran string, Anda bisa saja menyalin aliran file input ke aliran file output. Ini akan menghemat banyak waktu dan memori.
Zachary Kraus
2
untuk melakukan tes kecepatan, uji hal-hal dalam memmory jangan sampai ke disk IO, kecuali pengujian Anda pada SSD terbaru dan yang didedikasikan untuk aplikasi kinerja Anda. Saat komputer terus-menerus menulis ke disk, bahkan jika Anda tidak menyentuh keyboard.
user3800527