Kısa devre değerlendirmesi ne zaman kötüdür?


12

Biraz daha açık olmak gerekirse, farklı dillerle çok zaman harcadığımı söyleyeceğim. Ama şimdiye kadar ya her zaman kullanacak ya da hiç desteklemiyor.

Şimdi iş VB.net gerektiren projeler üzerinde başlıyor ve görüyorum ki hem AND hem de ANDALSO açısından . Birincisi kısa devre yapmaz, ikincisi yapar.

Peki bu nedenini merak etmemi sağlıyor? Bunun gibi bir düzene sahip olmak, birinin modları değiştirmek isteyebileceğini ima ediyor gibi görünüyor. Ancak Kısa Devre kullanmanın kötü bir şey olacağı durumları düşünemiyorum .

Bunun çok daha iyi bir seçenek haline gelebileceğini biliyorum, bu yüzden bunu başka bir yere koymam gerekirse bana nerede olduğunu söyle.

Her iki seçeneğe sahip olmanın neden kısa devre yapmaktan daha iyi olacağına dair en azından resmi bir cevap olduğunu umuyorum .



Yanıtlar:


5

Mantıksal bir ifadedeki bazı terimlerin yan etkileri olabilir. Bazen tüm yan etkilerin belirtilen sırayla gerçekleşmesini sağlamak gerekir ve hiçbiri atlanmaz ve mantığa kılavuzluk eden değerlendirme sonucudur:

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

Diğer durumlarda, daha önceki bir değerlendirme yanlış döndürürse, kalan terimlerin hiçbirini değerlendirmek istemezsiniz.

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

Bazıları, ikinci örnekte kısa devre davranışına güvenmenin kötü bir form olduğunu, ancak bunun kodlama tarzı ve inanç sistemlerine dönüştüğünü tartıştılar. Dünyada, bir dilin sağladığı hemen hemen her özelliğe dayanan çok iyi kod parçaları vardır ve tam da bu şekilde olur.

VB'nin ANDALSO'su net ve uygulamayı daha kabul edilebilir hale getirme çabası gibi görünüyor.

JimmyJames'in cevabında belirttiği gibi, kısa devre değerlendirmesi etrafında ölçülebilir performans etkileri olabilir. Mekanizmayı sağlamayan diller, ifadenin her terimini daima değerlendirirken, bunu sağlayanlar ekstra dal ifadeleri üretebilir. Her iki durumda da, büyük ölçüde terimlerin her birini değerlendirmek için gereken işleme adımlarının sayısına ve ayrıca derleyici ve CPU mimarilerine bağlıdır. Kodda ölçülü bir darboğaz olana ve nasıl hafifleteceğinize karar verene kadar bu tür şeyleri umursamazsınız. Kodunuzda kısa devre değerlendirmesine izin verme ile ilgili herhangi bir yap veya yap kuralları, daha yavaş koda neden olma ve erken optimizasyon yapma şansını kabaca eşit olarak değerlendirebilir, bu nedenle her zaman ölçün, ardından optimize edin.


4
Aslında doğru olsa da, harika bir tasarım değil.
Robert Harvey

2
@RobertHarvey, yan etkileri olmayan bir kontrol sistemi yazamıyorum ve sonuçlara tepki vermezsem sistemi doğru şekilde kontrol edemiyorum. Başka bir deyişle, üstesinden gelin;).
jwdonahue

7
Hayır, ancak bu yan etki yapan işlevlerin sonuçlarını boole değişkenlerine atayabilir, ifdurumunuzdaki bu değişkenleri kontrol edebilir ve kısa devre yapabilirsiniz. Bazı yönlerden stilistik bir ayrım olduğuna katılıyorum, ama işleri kristal berraklığında yapma erdemi var.
Robert Harvey

3
@jwdonahue Karışıklık riski düşükse "büyük kelimeler" kullanmak doğru olmaz. Karışıklık ve bunun gibi bir kod bloğunun belirli nüanslarını kaybetme riski son derece yüksektir ve mantık için felaket olabilir. Okuma geliştiricisini çok zor düşünmek asla iyi değildir.
jpmc26

5
"Mantıksal bir ifadedeki bazı terimlerin yan etkileri olabilir" - Bu açılış ifadesi doğru olsa da, bu cevabın yan etkilere güvenmenin kötü olduğuna işaret etmede başarısız olduğunu hissediyorum . Gerçekte, sahte değerlendirmeleri önlemek için kısa devre değerlendirmesine güvenmekten çok daha kötüdür. Bu cevabın önerdiği kötü biçim olabilir.
aroth

20

Görünüşe göre, sorunuz kısa devre genel olarak iyi veya kötü olmakla ilgili değil, VB.NET'in operatörlere neden ve onsuz operatör sağlamasıyla ilgili. Bunu akılda tutarak, cevap

kısa devre değerlendirmesi ne zaman kötüdür?

basitçe: geriye dönük uyumluluğu ihlal ettiğinde .

Tamam, şimdi VB.NET'in eski VB6 veya VBA ile çok geriye dönük uyumlu olmadığını söyleyebilirsiniz, ancak dilin en azından belirli bölümleri. Microsoft'un eski VE ve VEYA semantiğini (kısa devre olmadan) tutma kararı, eski VB programlarını VB.NET'e taşırken ortaya çıkma olasılığının çok daha düşük olmasını sağlamıştır.

Öte yandan, VB.NET dil tasarımcıları kısa devre yapmak için iyi bir fikir olabilir. Doğru hatırladığımda, ilk VB.NET ön sürüm sürümleri VE veya VEYA operatörlerine kısa devre sağladı, ancak geliştirici geri bildirimi o kadar kötü olmalı, VB.NET 1.0 ortaya çıkmadan önce MS bu kararı geri çekmelidir. Böylece tasarımcılar yeni anahtar kelimeler açısından ANDALSOve ORELSEgeriye dönük uyumluluk ve kullanışlılık arasında bir denge olarak uygulamaya karar verdiler .

IMHO bu iyi bir karardı. Son on yılda birkaç eski programı taşımak zorunda kaldım ve AND ve / veya OR (pun hedefli) dahil olmak üzere her mantık ifadesi için ağır bir etki analizi yapmak zorunda değilim, bu görevi çok daha kolay ve daha ekonomik hale getirdi. Öte yandan, VB.NET'te yeni bir mantıksal ifade yazmak zorunda kaldığımda, operatörler için varsayılan seçimim kısa devre formları, C, C ++, C # vb. birkaç deyimi daha özlü bir biçimde yazmam gerekiyor (ANDALSO'nun yazmak için 4 karaktere daha ihtiyacı olsa bile).

Eğer ikna değilseniz, Joel Spolsky'nin Mars Kulaklıkları hakkındaki harika makalesini okumanızı tavsiye ederim , bu da yazılım geliştirmedeki erken tasarım kararlarının neden söz konusu bileşen veya dil veya API belirli bir boyuttaki bir kullanıcı tabanına ulaştıktan sonra kolayca iptal edilemediğidir. .


Tamam, bu bir rant olarak nitelendiriliyor ve Mars Kulaklıklarına bağlantı hiç ilgili görünmüyor.
jwdonahue

6
@jwdonahue: Bunun neden bir rant olduğunu düşündüğün hakkında hiçbir fikrim yok, tam tersi. Ve Mars Kulaklıkları hakkındaki makale, birkaç yıl önce verilen yazılım geliştirmedeki bazı tasarım kararlarının, söz konusu bileşen veya dil veya API belirli bir boyuttaki bir kullanıcı tabanına ulaştıktan sonra neden kolayca iptal edilemeyeceğidir. Analojiyi kavramak gerçekten zor değil mi? VB6 geçmişte çok popülerdi ve eminim hala dünyadaki yüz binlerce şirket VB6 veya VBA'da çalışan kritik görev uygulamalarına sahip.
Doc Brown

"Mars başlıkları" makalesinin gerçekten nasıl uyduğunu tam olarak göremiyorum. X'ler ve Y'ler (örneğin somunlar ve cıvatalar) arasında birlikte çalışabilirliği sağlamak için gerekli olan şey, en kötü durumdaki somunun belirtilenden biraz daha kötü bir cıvatayı barındıracağı şekilde X ve Y için ayrı standartlara sahip olmasıdır. Somun veya cıvataları gereksiz yere pahalı hale getirmekten veya somunlar ve cıvatalar arasında gereksiz miktarda eğime sahip olmaktan kaçınmak için spesifikasyonlar yazmaya çalışılmalıdır, ancak her iki yarıyı ayrı ayrı belirtmek, birlikte çalışabilirliğin bir spesifikasyona sahip olmaktan çok daha güvenilir olmasını mümkün kılar her iki tarafa da hizmet eder.
supercat

3
@supercat: Bu, halihazırda ve kullanımda olan trilyonlarca somun (veya VB6 kod satırı) ile ilgilidir ve şimdi cıvatalar (veya bu durumda VB derleyici) daha yeni bir nesil ile değiştirilecektir. Mevcut somunlar sadece metrik olmayan cıvatalara uygunsa, daha yeni cıvataların sadece metrik sistem yapılması ekonomik değildir.
Doc Brown

tl; dr: VB, 1964'ten kalma bir dil olan BASIC'in bir lehçesidir ve BASIC'te Andişlem kısa devre yapmaz, SQL'de (1974), ne FORTRAN'da (1956) ne de Pascal'da (1970).
Ben

3

kısa devre değerlendirmesi ne zaman kötüdür?

Kötü olurlar , boole genel sonucunun değerlendirilmesinde yürütülmesini beklediğiniz ifadelerin yan etkilerine güvenmeye başlar başlamaz.


1

Dikkat : Bu, neredeyse tüm durumlarda, geliştiricilerin endişelenmemesi gerektiğinden biraz ezoteriktir. Ancak ... yürütmede dallanma yarattığı için koşullu değerlendirme nedeniyle bir performans isabeti olabilir. Kısa devre olmayan bir işlem dallanmaz ve daha öngörülebilirdir.

Bunun nadiren önemli olmasının nedeni, maliyetin tipik olarak küçük olması ve genellikle ikinci (veya üçüncü vb.) Durumun değerlendirilmesi maliyetinden daha ağır basmasıdır. Bu, yalnızca yüksek performans gerektiğinde hesaplamalı olarak pahalı rutinlerde önemli olacaktır ve yine de önemli olmayabilir.


Bence şu ana kadar sadece mantıklı bir ifadeyi optimize edebiliyorsunuz, sonunda şubeleri almak zorundasınız.
jwdonahue

@jwdonahue Anlamını anlamadım. Afedersiniz.
JimmyJames

Burada kombinatoryal mantıktan bahsediyoruz. Kısa devre değerlendirmesi ya da değil, daha önceki bir dönemin sonucuna bağlı olarak değerlendirilmesi gereken bir veya daha fazla teriminiz var. Dolayısıyla dallanma söz konusudur.
jwdonahue

1
@jwdonahue Tabii ki her kısa devre ek bir dal. Bazı senaryolarda, iki ifadenin (örneğin) yürütülmesi, ikincisini çalıştırmadan önce birincinin sonucunu kontrol etmekten daha hızlıdır, ancak ikincisinin alakasız olması durumunda bile. Yine, bu nadiren önemlidir. Birinin bana bunun için yaptığı dava, çok basit değerlendirmelerinizin olduğu matris çarpımı gibi şeyler içindi.
JimmyJames

1
Cevabımı size kredi ile güncelledim.
jwdonahue

0

Pascal, AND ve OR'nin kısa devre değerlendirmesi kullanıp kullanmadığını belirlemedi ve size her iki dünyanın da en kötüsünü verdi.

C ve C ++ bitsel işlemlere sahiptir & ve | bu da size pratikte kısa devre olmayan işlemler sağlar. Ve derleyiciler, gözlemlenebilir bir fark yaratmazsa, istedikleri şekilde değerlendirme yapmakta serbesttirler.


@Deduplicator: Belirtildiği gibi Pascal , AND / OR'nin kısa devre değerlendirmesi kullanıp kullanmayacağını tanımlamamıştır . Bu "bilmemek" anlamına gelir.
supercat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.