Rumah > pembangunan bahagian belakang > C++ > C dan C sangat pantas?

C dan C sangat pantas?

Susan Sarandon
Lepaskan: 2024-12-07 09:25:13
asal
944 orang telah melayarinya

C and C   are really so fast?

Sepanjang masa saya terlibat dengan pengaturcaraan, saya mendengar bahawa C dan C ialah standard kelajuan. Terpantas daripada yang terpantas, disusun terus ke kod pemasangan, tiada apa yang boleh bersaing dalam kelajuan dengan C atau C . Dan, nampaknya tiada siapa yang mencabar kepercayaan biasa itu.

Prestasi pengkomputeran

Operasi aritmetik dengan nombor, jelas sekali, mesti berfungsi dengan ketara lebih pantas dalam C berbanding dalam mana-mana bahasa lain. Tetapi adakah mereka?
Beberapa waktu lalu saya memutuskan untuk menulis satu set penanda aras mudah untuk dilihat oleh pelbagai bahasa, betapa besarnya perbezaan kelajuan sebenarnya.
Idea adalah mudah: untuk mencari jumlah satu bilion nombor integer, bermula dari sifar, menggunakan pengkomputeran lurus ke hadapan. Sesetengah penyusun (rustc, sebagai contoh) menggantikan kitaran mudah sedemikian dengan ungkapan formula, yang, sudah tentu, akan dinilai dalam masa yang tetap. Untuk mengelakkannya dengan penyusun sedemikian. Saya menggunakan yang serupa dalam operasi kos dengan nombor, seperti bitwise atau.
Selepas saya mendapat keputusan, saya sangat terkejut. Pandangan dunia saya terbalik, dan saya terpaksa mempertimbangkan semula semua yang saya tahu tentang kelajuan bahasa pengaturcaraan.
Anda boleh melihat keputusan saya dalam jadual di bawah :

Linux 64bit, 1.1 GHz ​​CPU, 4GB RAM

Bahasa compiler/version/args masa Karat (
Language compiler/version/args time
Rust (bitwise or instead of ) rustc 1.75.0 with -O3 167 ms
C gcc 11.4.0 with -O3 335 ms
NASM 2.15.05 339 ms
Go 1.18.1 340 ms
Java 17.0.13 345 ms
Common Lisp SBCL 2.1.11 1 sec
Python 3 pypy 3.8.13 1.6 sec
Clojure 1.10.2 9 sec
Python 3 cpython 3.10.12 26 sec
Ruby 3.0.2p107 38 sec
bitwise atau bukannya ) rustc 1.75.0 dengan -O3 167 ms C gcc 11.4.0 dengan -O3 335 ms NASM 2.15.05 339 ms Pergi 1.18.1 340 ms Jawa 17.0.13 345 ms Bincang Biasa SBCL 2.1.11 1 saat Python 3 pypy 3.8.13 1.6 saat Clojure 1.10.2 9 saat Python 3 cpython 3.10.12 26 saat Ruby 3.0.2p107 38 saat

Semua sumber ujian yang mungkin anda temui di sini :
https://github.com/Taqmuraz/speed-table

Jadi, seperti yang mungkin kita lihat, C tidak jauh lebih pantas daripada Java, perbezaannya adalah kira-kira 3%. Selain itu, kami melihat bahawa bahasa terkumpul lain sangat hampir dalam prestasi operasi aritmetik dengan C (Karat lebih cepat). Bahasa dinamik, yang disusun dengan Pengkompil JIT, menunjukkan hasil yang lebih teruk -- kebanyakannya kerana operasi aritmetik dibalut ke dalam fungsi yang dihantar secara dinamik di sana.
Bahasa dinamik yang ditafsirkan tanpa pengkompil JIT menunjukkan prestasi paling teruk, bukan kejutan.

Prestasi peruntukan memori

Selepas kekalahan teruk itu, peminat C akan mengatakan bahawa peruntukan memori dalam C adalah lebih cepat, kerana anda memperuntukkannya terus daripada sistem, bukan meminta GC.
Sekarang dan selepas ini saya akan menggunakan istilah GC sebagai pengumpul sampah dan sebagai timbunan terurus, bergantung pada konteks.
Jadi, mengapa orang berfikir, bahawa GC sangat lambat? Malah, GC mempunyai memori yang telah diperuntukkan terlebih dahulu dan peruntukan adalah hanya mengalihkan penunjuk ke kanan. Kebanyakannya GC mengisi memori yang diperuntukkan dengan sifar menggunakan panggilan sistem, serupa dengan memset daripada C, jadi ia mengambil masa malar. Walaupun peruntukan memori dalam C mengambil masa yang tidak ditentukan, kerana ia bergantung pada sistem dan memori yang telah diperuntukkan.
Tetapi, walaupun mempertimbangkan pengetahuan ini, saya tidak dapat mengharapkan hasil yang begitu baik dari Java, yang mungkin anda lihat dalam jadual berikut :

1.1 GHz 2 cores, 4 GB RAM
Running tests on single thread.
Result format : "Xms-Yms ~Z ms" means tests took from X to Y milliseconds, and Z milliseconds in average
1.1 GHz ​​2 teras, 4 GB RAM Menjalankan ujian pada urutan tunggal. Format keputusan : "Xms-Yms ~Z ms" bermaksud ujian yang diambil dari X hingga Y milisaat dan Z milisaat secara purata

Memperuntukkan tatasusunan integer

integers array size times Java 17.0.13 new[] C gcc 11.4.0 malloc Common Lisp SBCL 2.1.11 make-array
16 10000 0-1ms, ~0.9ms 1-2ms, ~1.2ms 0-4ms, ~0.73ms
32 10000 1-3ms, ~1.7ms 1-3ms, ~1.7ms 0-8ms, ~2.ms
1024 10000 6-26ms, ~12ms 21-46ms, ~26ms 12-40ms, ~7ms
2048 10000 9-53ms, ~22ms 24-52ms, ~28ms 12-40ms, ~19ms
16 100000 0-9ms, ~2ms 6-23ms, ~9ms 4-24ms, ~7ms
32 100000 0-14ms, ~3ms 10-15ms, ~11ms 3-8ms, ~7ms
1024 100000 0-113ms, ~16ms 234-1156ms, ~654ms 147-183ms, ~155ms
2048 100000 0-223ms, ~26ms 216-1376ms, ~568ms 299-339ms, ~307ms

Memperuntukkan contoh kelas Orang dengan satu medan integer.

how many instances Java 17.0.3 new Person(n) C g 11.4.0 new Person(n)
100000 0-6ms, ~1.3ms 4-8ms, ~5ms
1 million 0-11ms, ~2ms 43-69ms, ~47ms
1 billion 22-50ms, ~28ms process terminated

Semua sumber ujian yang mungkin anda temui di sini :
https://github.com/Taqmuraz/alloc-table

Di sana saya menguji empat bahasa secara keseluruhan: C, C , Java dan Lisp. Dan, bahasa dengan GC sentiasa menunjukkan hasil yang lebih baik, walaupun saya mengujinya dengan lebih ketat, berbanding C dan C . Sebagai contoh, di Java saya memperuntukkan memori melalui panggilan fungsi maya, jadi ia mungkin tidak dioptimumkan secara statik, dan dalam Lisp saya menyemak elemen pertama tatasusunan yang diperuntukkan, jadi pengkompil tidak akan melangkau panggilan peruntukan.

Melepaskan ingatan

Peminat C masih bermotivasi untuk melindungi kepercayaan mereka, jadi, mereka berkata "Ya, anda memperuntukkan memori lebih cepat, tetapi anda perlu melepaskannya selepas itu!".
betul. Dan, tiba-tiba, GC mengeluarkan memori lebih cepat, daripada C. Tetapi bagaimana? Bayangkan, kami membuat 1 juta peruntukan daripada GC, tetapi kemudian kami hanya mempunyai 1000 objek yang dirujuk dalam program kami. Dan, katakan, objek tersebut diedarkan melalui semua rentang memori yang panjang itu. GC melakukan pengesanan tindanan, mencari 1000 objek "hidup" itu, mengalihkannya ke puncak timbunan generasi sebelumnya dan meletakkan penuding puncak timbunan selepas yang terakhir daripadanya. Itu sahaja.
Jadi, tidak kira, berapa banyak objek yang anda peruntukkan, masa kerja GC ditentukan oleh berapa banyak objek yang anda simpan selepas.
Dan, bertentangan dengan itu, dalam C anda perlu melepaskan semua memori yang diperuntukkan secara manual, jadi, jika anda memperuntukkan memori 1 juta kali, anda perlu membuat 1 juta panggilan keluaran juga (atau anda akan mengalami kebocoran memori). Ini bermakna, O(1)-O(n) daripada GC menentang O(n) atau lebih teruk daripada C, di mana n ialah bilangan peruntukan yang berlaku sebelum ini.

Ringkasan

Jadi, saya ingin menyatukan kemenangan bahasa kutipan sampah ke atas C dan C . Berikut ialah jadual ringkasan :

permintaan bahasa dengan GC C/C aritmetik berpuasa dengan
demands languages with GC C/C
arithmetic fast with JIT fast
allocating memory fast O(1) slow
releasing memory fast O(1) best case, O(n) worst case O(n) or slower
memory safe yes no
JIT cepat memperuntukkan memori cepat O(1) perlahan melepaskan ingatan cepat O(1) kes terbaik, O(n) kes terburuk O(n) atau lebih perlahan memori selamat ya tidak

Sekarang kita boleh lihat -- kutipan sampah bukanlah kejahatan yang perlu, tetapi perkara terbaik yang kita hanya ingin miliki. Ia memberi kita keselamatan dan prestasi kedua-duanya.

Penghormatan kepada C

Walaupun C menunjukkan keputusan yang lebih teruk pada ujian saya, ia masih merupakan bahasa yang penting dan ia mempunyai medan aplikasi sendiri. Artikel saya tidak bertujuan untuk penolakan atau pemansuhan C. C tidaklah teruk, cuma ia tidaklah sehebat yang difikirkan orang. Banyak projek yang baik runtuh hanya kerana sesetengah orang memutuskan untuk menggunakan C dan bukannya Java, sebagai contoh, kerana mereka telah diberitahu bahawa C adalah lebih pantas, dan Java adalah sangat perlahan kerana pengumpulan sampah. C adalah baik, apabila kita menulis program yang sangat kecil dan mudah. Tetapi, saya tidak akan mengesyorkan menulis program atau permainan yang kompleks dengan C.

C berbeza

C tidak mudah, tidak fleksibel, mempunyai sintaks yang berlebihan dan spesifikasi yang terlalu rumit. Pengaturcaraan dengan C anda tidak akan melaksanakan idea sendiri tetapi melawan dengan ralat pengkompil dan ingatan 90% pada setiap masa.
Artikel ini menyasarkan penolakan C , kerana kelajuan dan prestasi hanyalah alasan orang ramai menggunakan bahasa ini dalam pembangunan perisian. Menggunakan C , anda membayar dengan masa anda, prestasi program anda dan kesihatan mental anda. Jadi, apabila anda mempunyai pilihan antara C dan sebarang bahasa lain, saya harap anda memilih yang terakhir.

Atas ialah kandungan terperinci C dan C sangat pantas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan