Kapan evaluasi hubung singkat buruk?


12

Agar lebih jelas, saya akan menyatakan bahwa saya telah menghabiskan banyak waktu dengan berbagai bahasa. Tetapi sampai sekarang sudah baik itu akan menggunakannya sepanjang waktu atau tidak mendukung sama sekali.

Sekarang pekerjaan telah saya mulai pada proyek yang membutuhkan VB.net dan saya melihatnya menyediakan kedua - duanya dalam hal AND dan ANDALSO . Yang pertama tidak korsleting, dan yang kedua tidak.

Jadi ini membuat saya bertanya-tanya mengapa? Memiliki pengaturan seperti ini tampaknya menyiratkan bahwa itu akan muncul cukup sering sehingga seseorang ingin beralih mode. Tapi saya tidak bisa memikirkan situasi di mana itu akan menjadi hal yang buruk untuk menggunakan Sirkuit Pendek .

Saya tahu ini bisa menjadi pilihan, jadi jika saya harus meletakkan ini di tempat lain, katakan saja di mana.

Meskipun saya berharap setidaknya ada jawaban resmi, mengapa memiliki kedua opsi akan lebih baik daripada selalu melakukan Sirkuit Pendek , ketika tersedia.



Jawaban:


5

Beberapa istilah dalam ekspresi logis dapat memiliki efek samping. Kadang-kadang diperlukan untuk memastikan semua efek samping terjadi dalam urutan yang dinyatakan, dan tidak ada yang dilewati dan itu adalah hasil evaluasi yang memandu logika:

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

Dalam kasus lain, Anda tidak ingin mengevaluasi salah satu istilah yang tersisa jika evaluasi sebelumnya menghasilkan false.

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

Beberapa orang akan / berpendapat bahwa mengandalkan perilaku hubung-pendek dalam contoh kedua adalah bentuk yang buruk, tetapi itu masuk ke gaya pengkodean dan sistem kepercayaan. Ada banyak bit kode yang sangat bagus di dunia yang bergantung pada hampir setiap fitur yang disediakan bahasa, dan memang begitu adanya.

ANDALSO VB renyah dan tampaknya menjadi upaya untuk membuat praktik lebih dapat diterima.

Seperti yang ditunjukkan JimmyJames dalam jawabannya, mungkin ada implikasi kinerja yang dapat diukur seputar evaluasi hubung singkat. Bahasa yang tidak menyediakan mekanisme, selalu mengevaluasi setiap istilah dari ekspresi, sedangkan yang menyediakannya, dapat menghasilkan pernyataan cabang tambahan. Either way, banyak tergantung pada jumlah langkah pemrosesan yang diperlukan untuk mengevaluasi setiap persyaratan dan juga pada kompiler dan arsitektur CPU. Anda biasanya tidak akan peduli tentang hal-hal seperti itu sampai Anda memiliki hambatan yang diukur dalam kode dan perlu mencari cara untuk meringankannya. Aturan apa pun yang dilakukan atau tidak terkait dengan mengizinkan evaluasi hubung singkat dalam kode Anda akan memiliki peluang yang kira-kira sama untuk menyebabkan kode lebih lambat dan mengoptimalkan lebih awal bisa menghabiskan banyak waktu, jadi selalu ukur, lalu optimalkan.


4
Meskipun secara faktual benar, itu bukan desain yang bagus.
Robert Harvey

2
@ RobertTarvey, saya tidak bisa menulis sistem kontrol yang tidak memiliki efek samping dan saya tidak bisa mengendalikan sistem dengan benar jika saya tidak bereaksi terhadap hasil. Dengan kata lain, lupakan saja;).
jwdonahue

7
Tidak, tetapi Anda dapat menetapkan hasil dari fungsi-fungsi yang memengaruhi samping tersebut ke variabel boolean, periksa variabel-variabel tersebut dalam ifkondisi Anda dan masih hubungan pendek. Saya setuju bahwa itu adalah, dalam beberapa hal, perbedaan gaya, tetapi memang memiliki keutamaan membuat hal-hal sejernih kristal.
Robert Harvey

3
@ jwdonahue Tidak apa-apa menggunakan "kata-kata besar" jika risiko kebingungan rendah. Risiko kebingungan dan kehilangan nuansa tertentu dari blok kode seperti ini sangat tinggi dan dapat menjadi bencana bagi logika. Tidak pernah baik untuk membuat pengembang membaca berpikir sangat keras.
jpmc26

5
"Beberapa istilah dalam ekspresi logis dapat memiliki efek samping" - Meskipun pernyataan pembuka ini benar, saya merasa jawaban ini gagal karena tidak menunjukkan bahwa mengandalkan efek samping itu buruk . Bahkan jauh lebih buruk daripada mengandalkan evaluasi hubung singkat untuk mencegah evaluasi palsu. Yang disarankan jawaban ini mungkin bentuk yang buruk.
aroth

20

Tampaknya, pertanyaan Anda bukan tentang hubungan arus pendek yang baik atau buruk secara umum, tetapi tentang mengapa VB.NET memberikan operator dengan dan tanpa itu. Dengan mengingat hal ini, jawabannya

kapan evaluasi hubung singkat buruk?

sederhana: ketika melanggar kompatibilitas ke belakang .

Ok, sekarang Anda dapat mengatakan VB.NET tidak kompatibel dengan VB6 atau VBA lama, namun setidaknya bagian-bagian tertentu dari bahasa tersebut. Keputusan Microsoft untuk menjaga semantik AND dan OR lama (tanpa hubungan arus pendek) membuat kategori kesalahan yang sangat kecil kemungkinannya terjadi ketika ketika porting program VB lama ke VB.NET.

Di sisi lain, perancang bahasa VB.NET mungkin membagikan pendapat Anda tentang hubungan arus pendek menjadi hal yang baik. Ketika saya ingat dengan benar, versi pra-rilis VB.NET pertama menyediakan hubungan pendek DAN atau OR dengan operator, tetapi umpan balik pengembang pastilah sangat buruk MS menarik keputusan ini sebelum VB.NET 1.0 muncul. Jadi para desainer memutuskan untuk menerapkannya dalam hal kata kunci baru ANDALSOdan ORELSEsebagai trade-off antara kompatibilitas mundur dan kegunaan.

IMHO ini adalah keputusan yang bagus. Saya harus mem-porting beberapa program yang lebih tua dalam dekade terakhir, dan tidak harus membuat analisis dampak yang berat untuk setiap ekspresi logika termasuk DAN dan / atau OR (pun intended) membuat tugas itu jauh lebih mudah dan lebih ekonomis. Di sisi lain, setiap kali saya harus menulis ekspresi logis baru di VB.NET, pilihan default saya untuk operator adalah bentuk hubung singkat, itulah yang biasa saya gunakan dari C, C ++, C # dll, dan memungkinkan saya menulis beberapa idiom dalam bentuk yang lebih ringkas (walaupun ANDALSO membutuhkan 4 karakter lebih banyak untuk diketik).

Jika Anda tidak yakin, saya sarankan untuk membaca artikel hebat Joel Spolsky tentang Mars Headset , yang tentang mengapa keputusan desain awal dalam pengembangan perangkat lunak tidak dapat dengan mudah dicabut setelah komponen atau bahasa atau API yang dipertaruhkan telah mencapai basis pengguna dengan ukuran tertentu. .


Ok, ini memenuhi syarat sebagai kata-kata kasar dan tautan ke Headset Mars sepertinya tidak terkait sama sekali.
jwdonahue

6
@ jwdonahue: Saya tidak tahu mengapa Anda berpikir ini kata-kata kasar, justru sebaliknya. Dan artikel tentang Headset Mars adalah tentang mengapa beberapa keputusan desain dalam pengembangan perangkat lunak yang dibuat beberapa dekade yang lalu tidak dapat dengan mudah dicabut setelah komponen atau bahasa atau API yang dipertaruhkan telah mencapai basis pengguna dengan ukuran tertentu. Bukankah analoginya sangat sulit untuk dipahami? VB6 sangat populer di masa lalu, dan saya yakin masih ratusan ribu perusahaan di dunia memiliki aplikasi mission mission yang berjalan di VB6 atau VBA.
Doc Brown

Saya tidak begitu mengerti bagaimana artikel "Mars Headests" benar-benar cocok. Apa yang diperlukan untuk memastikan interoperabilitas antara X dan Y (mis. Mur dan baut) adalah memiliki standar terpisah untuk X dan Y, sedemikian sehingga mur terburuk akan mengakomodasi baut yang sedikit lebih buruk dari yang ditentukan, dan sebaliknya. Kita harus mencoba menulis spesifikasi untuk menghindari membuat mur atau baut yang tidak perlu mahal, atau memiliki jumlah slop yang tidak perlu antara mur dan baut, tetapi menentukan kedua bagian secara terpisah memungkinkan untuk memastikan interoperabilitas jauh lebih andal daripada mencoba memiliki satu spesifikasi melayani kedua belah pihak.
supercat

3
@supercat: ini tentang sudah triliunan kacang (atau baris kode VB6) yang ada dan sedang digunakan, dan sekarang baut (atau dalam hal ini penyusun VB) akan diganti oleh generasi yang lebih baru. Jika mur yang ada hanya cocok untuk baut non-metrik, tidak ekonomis untuk membuat sistem metrik baut yang lebih baru saja.
Doc Brown

tl; dr: VB adalah dialek BASIC, sebuah bahasa yang berasal dari tahun 1964, dan dalam BASIC Andoperasinya tidak mengalami hubungan pendek, tidak juga dalam SQL (1974), maupun FORTRAN (1956), atau Pascal (1970).
Ben

3

kapan evaluasi hubung singkat buruk?

Mereka menjadi buruk , segera setelah Anda mulai mengandalkan efek samping dari ekspresi yang Anda harapkan akan dieksekusi dalam evaluasi hasil keseluruhan boolean.


1

Peringatan : Ini agak esoteris karena dalam hampir semua kasus, pengembang tidak perlu khawatir. Tapi ... mungkin ada hit kinerja karena evaluasi bersyarat karena menciptakan percabangan dalam eksekusi. Operasi hubung singkat tidak bercabang dan lebih mudah diprediksi.

Alasan mengapa hal ini jarang penting adalah bahwa biayanya biasanya kecil dan juga biasanya lebih besar daripada biaya mengevaluasi kondisi kedua (atau ketiga, dll.). Ini hanya akan menjadi masalah dalam rutinitas mahal komputasi ketika kinerja tinggi diperlukan dan itu mungkin masih tidak menjadi masalah juga.


Saya pikir Anda hanya dapat mengoptimalkan pernyataan logis sejauh ini, akhirnya Anda harus mengambil cabang.
jwdonahue

@ jwdonahue Saya tidak mengerti maksud Anda. Maaf.
JimmyJames

Kita berbicara tentang logika kombinatorial di sini. Evaluasi hubung singkat atau tidak, Anda memiliki satu atau lebih istilah yang harus dievaluasi tergantung pada hasil istilah sebelumnya. Karena itu, percabangan terlibat.
jwdonahue

1
@ jwdonahue Tentu saja, tetapi setiap korsleting adalah cabang tambahan. Dalam skenario tertentu mengeksekusi dua ekspresi (misalnya) lebih cepat daripada memeriksa hasil yang pertama sebelum mengeksekusi yang kedua bahkan jika itu sering terjadi bahwa yang kedua tidak relevan. Sekali lagi, ini jarang penting. Kasus seseorang membuatkan saya untuk ini adalah untuk hal-hal seperti perkalian matriks di mana Anda memiliki banyak evaluasi sederhana.
JimmyJames

1
Saya memperbarui jawaban saya dengan kredit untuk Anda.
jwdonahue

0

Pascal tidak menentukan apakah AND dan OR menggunakan evaluasi hubung singkat atau tidak, memberi Anda yang terburuk dari kedua dunia.

C dan C ++ memiliki operasi bitwise & dan | yang dalam praktiknya memberi Anda operasi hubung singkat. Dan kompiler bebas untuk mengevaluasi apa pun yang mereka suka jika itu tidak membuat perbedaan yang bisa diamati.


@Dupuplikator: Seperti disebutkan, Pascal tidak menentukan apakah AND / OR menggunakan evaluasi hubung singkat. Itu berarti "tidak tahu".
supercat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.