Mengapa tidak menggunakan kode aman yang tidak dikelola di C #

10

Ada opsi dalam C # untuk mengeksekusi kode yang tidak dicentang. Biasanya tidak disarankan untuk melakukannya, karena kode yang dikelola jauh lebih aman dan mengatasi banyak masalah.

Namun saya bertanya-tanya, jika Anda yakin kode Anda tidak akan menyebabkan kesalahan, dan Anda tahu bagaimana menangani memori lalu mengapa (jika Anda suka kode cepat) ikuti saran umum?

Saya bertanya-tanya karena saya menulis sebuah program untuk kamera video, yang memerlukan manipulasi bitmap yang sangat cepat. Saya membuat beberapa algoritma grafis cepat sendiri, dan mereka bekerja sangat baik pada bitmap menggunakan kode yang tidak dikelola.

Sekarang saya bertanya-tanya secara umum, jika Anda yakin Anda tidak memiliki kebocoran memori, atau risiko crash, mengapa tidak menggunakan kode yang tidak dikelola lebih sering?

PS latar belakang saya: Saya agak masuk ke dunia pemrograman ini dan saya bekerja sendiri (saya melakukannya selama beberapa tahun) dan jadi saya harap pertanyaan desain perangkat lunak ini tidak aneh. Saya tidak benar-benar memiliki orang lain di luar sana seperti seorang guru untuk menanyakan hal-hal seperti itu.

pengguna613326
sumber
8
unsafeberarti "tahu apa yang Anda lakukan, dan timbang manfaatnya terhadap risikonya." Saya telah menggunakan unsafebeberapa kali, dan itu selalu untuk sesuatu yang sangat spesifik terkait dengan kinerja yang dapat ditutup dengan metode sendiri. Saya tidak menggunakannya sebagai teknik pemrograman umum, karena sebagian besar waktu manfaat kinerja tambahan tidak sebanding dengan hilangnya keselamatan.
Robert Harvey
14
Saya telah menulis banyak kode selama bertahun-tahun yang terkadang macet atau mengalami kebocoran memori, yang saya yakin tidak memiliki kebocoran memori atau risiko kerusakan.
whatsisname
1
Berikut ini adalah unsafecontoh kasus penggunaan yang baik : stackoverflow.com/q/11660127/102937
Robert Harvey
3
Saya kira kode bitmap Anda masih memiliki bug, tetapi Anda tidak mendeteksinya. Dan bahkan jika itu tidak terjadi, tunggu sampai Anda harus menerapkan beberapa persyaratan baru ke dalam kode yang ada.
Doc Brown
1
Karena meskipun Anda yakin kode Anda tidak akan menyebabkan kesalahan, kode itu masih menyebabkan kesalahan.
user253751

Jawaban:

27

Yah, itu sebagian besar kasus pepatah lama usia

  • Jangan optimalkan
  • (hanya untuk ahli) Jangan optimalkan

Tapi sebenarnya saya bisa memikirkan tiga alasan utama untuk menghindari kode yang tidak aman.

  1. Bug : Bagian penting dari pertanyaan Anda adalah "jika Anda yakin kode Anda tidak akan menyebabkan kesalahan". Nah, bagaimana Anda bisa benar-benar yakin? Apakah Anda menggunakan prover dengan metode formal yang menjamin kode Anda benar? Satu hal yang pasti dalam pemrograman, dan itu adalah bahwa Anda akan memiliki bug. Saat Anda melepas pengaman, Anda mengizinkan bug jenis baru merayap. Ketika Anda membiarkan pengumpul sampah mengurus memori untuk Anda, banyak masalah hilang.

  2. Tidak selalu secepat yang Anda pikirkan : Poin lainnya adalah: tergantung pada masalahnya, keuntungannya mungkin tidak terlalu bagus. Meskipun saya tidak dapat menemukan mereka sekarang, saya ingat sebuah penelitian oleh Google membandingkan kecepatan Java, Scala, Go dan C ++. Setelah dioptimalkan ke tanah, tentu saja C ++ jauh lebih cepat. Tetapi algoritma yang diprogram dengan cara "idiomatik" tidak terlalu cepat. Idiomatik dalam arti bahwa mereka menggunakan struktur dan idiom standar (stl container, tidak ada loop terbuka, dll). Microsoft melakukan percobaan serupa dengan C # dan C ++. Raymond Chen, salah satu Insinyur Microsoft top, harus menulis sendiri implementasi std :: string untuk mengalahkan C #. (lihat: http://www.codinghorror.com/blog/2005/05/on-managed-code-performance-again.html) Untuk upaya yang jauh lebih sedikit, Anda mendapatkan kinerja yang cukup baik dalam kode yang dikelola, jadi seringkali tidak sepadan dengan masalahnya.

  3. Dapat digunakan kembali : Kode tidak aman hanya dapat digunakan di lingkungan kepercayaan penuh. Misalnya, di server ASP.NET, Anda biasanya tidak dapat menggunakan kode yang tidak aman, karena akan cukup mudah untuk memperkenalkan kerentanan dengan buffer overflow. Contoh lain adalah clickonce. Atau jika aplikasi Anda diakses dari jaringan berbagi. Jadi, jika Anda berencana untuk menggunakan kode Anda dalam berbagai skenario penerapan, kode yang tidak aman keluar dari permainan.

Jadi pada dasarnya: ini disukai karena mungkin memperkenalkan bug yang tidak perlu, mungkin tidak ada untungnya sama sekali, dan mengurangi penggunaan kembali kode Anda.

Tetapi jika skenario Anda benar-benar membutuhkannya untuk kinerja (dan Anda memiliki data untuk membuktikannya), Anda adalah seorang programmer berpengalaman yang tahu bagaimana menangani memori dan kode Anda akan digunakan dalam lingkungan yang terkontrol, maka tentu saja, lakukanlah.

Laurent Bourgault-Roy
sumber
4

Di satu sisi, kode yang tidak dikelola adalah bentuk pembayaran: Anda membeli eksekusi lebih cepat dengan upaya pengembangan ekstra. Memang, kode yang tidak dikelola membutuhkan lebih banyak waktu untuk mengembangkan, men-debug, dan memelihara. Melakukannya dengan benar adalah tantangan bagi sebagian besar peserta. Di satu sisi, ini mirip dengan pemrograman dalam perakitan: tentu saja, Anda dapat menekan lebih banyak daya dari CPU Anda jika Anda menulis dalam perakitan * , tetapi Anda "menghabiskan" lebih banyak upaya untuk menempuh rute itu.

Terkadang, perbedaan waktu pengembangan sangat signifikan - hari bukan jam. Namun, perbedaan dalam kecepatan eksekusi hampir tidak sedramatis itu. Itulah sebabnya pengembangan kode yang tidak dikelola dicadangkan untuk situasi yang mirip dengan yang Anda jelaskan di pos Anda, yang terlokalisasi, mandiri, implementasi dari algoritma yang membutuhkan sumber daya, seperti pemrosesan audio dan video.

Pada dasarnya, jawaban untuk pertanyaan Anda mirip dengan jawaban mengapa tidak semua orang mengendarai Ferrari: ini mobil yang jauh lebih baik, bukan? (Un) untungnya, tidak semua orang mampu membelinya.


* Kemajuan beberapa dekade terakhir dalam teknologi optimisasi dalam kompiler telah mempersempit kesenjangan ini sehingga tidak lagi menjadi taruhan yang pasti.

dasblinkenlight
sumber
0

Karena menjadi "yakin" tentang kebenaran atau kendala lain dalam arti matematika (yaitu Anda punya bukti) adalah masalah yang sangat sulit untuk bahasa imperatif. Program sering kali memiliki jumlah status yang sangat tinggi sehingga tidak mungkin untuk memverifikasi bahkan dengan memeriksa setiap kondisi yang memungkinkan. Dan menciptakan bukti konstruktif bukanlah sesuatu yang dapat Anda otomatisasi.

Jadi alasannya adalah bahwa asuransi yang mengelola eksekusi memberikan paling sering menimbang keuntungan kecil yang Anda dapatkan dengan kode yang tidak aman. Tentu saja, ini tergantung pada kasus penggunaan khusus juga.

Tamás Szelei
sumber
1
Saya tidak berpikir itu ada hubungannya dengan kebenaran atau kesederhanaan untuk alasan ..
Jimmy Hoffa
Tidak ada yang berbicara tentang bukti formal kebenaran.
1
Saya yakin posting Anda tidak tepat sasaran, namun saya tidak merumuskan bukti formal. Demikian juga, saya dapat memastikan program saya benar (mis. Setelah pengujian ekstensif, debugging, dan penggunaan dunia nyata berkepanjangan tanpa ada bug yang muncul) tanpa membuktikannya sekali dan untuk semua. Penafsiran ini jauh lebih dekat dengan apa yang kebanyakan orang maksudkan ketika mereka mengatakan "yakin itu benar". Metode formal adalah perhatian khusus, dan sepenuhnya tidak dipertimbangkan oleh sebagian besar pengembang.
1
Saya tidak melihat pertanyaan seperti itu. Pertanyaannya, ketika saya membacanya, adalah tentang mengapa jalan keluar dari dunia terkelola tidak / seharusnya tidak digunakan lebih sering (menyiratkan bahwa default ke kode yang dikelola masuk akal). Dalam kasus manapun, jika Anda ingin menjawab bahwa pertanyaan (dengan menunjukkan kekerasan menjamin ketepatan), Anda dapat melakukannya tanpa berbicara tentang mutlak, resmi jaminan kebenaran. Jawaban Anda pada saat ini hanya berkisar pada bukti yang lengkap dan benar untuk bahasa yang sangat penting. Tapi itu berlebihan, dan saya pikir bukti tentang C # dikelola sama (atau hampir sama) sulit.
1
@ Ikan: Saya bisa melihat apa yang Anda katakan. Ada korelasi antara sesuatu yang sulit dibuktikan dan sesuatu yang sulit untuk dipikirkan. Jika sulit dibuktikan benar, maka sangat mungkin sulit untuk memastikan itu benar.
Michael Shaw
0

Singkatnya, tidak ada yang menghalangi Anda dalam melakukan semua yang bekerja dan mengelola bit dan baut program Anda di lingkungan C ++. Karena Anda cukup yakin bahwa Anda dapat dengan benar mengelola semua simpai dan kebocoran memori tanpa pengumpul sampah maka Anda dapat melakukannya di C ++ :)

Sebaliknya, C # memiliki keunggulan dalam menyediakan lingkungan pengembangan yang diketik / diketik dengan aman untuk dijalankan dengan aman dalam kerangka NET.

Kemungkinan penarikan kembali pemrograman kode yang tidak dikelola adalah waktu pengembangan yang lebih lama, alokasi waktu untuk pengujian terperinci. Anda tentu saja akan mendapatkan kecepatan pemrosesan dan kontrol lebih besar atas bagaimana perangkat lunak Anda berjalan.

Dengan demikian, opsi untuk bekerja dengan kode yang tidak dikelola di .NET Framework mulai dari 4.0 adalah opsi untuk kasus tepi ketika Anda yakin bahwa itu mungkin membawa Anda keuntungan daripada tidak menggunakannya ...

Yusubov
sumber
Aha thats menarik Anda melihat saya dari dunia pengontrol mikro dan biasanya ada satu menulis layak c ++ ada sedikit ruang untuk kesalahan dan desain yang baik dari perangkat lunak adalah hal utama yang harus dilakukan
user613326