Kısa devre değerlendirmesi - Short-circuit evaluation

Kısa devre değerlendirmesi , minimum değerlendirme veya McCarthy değerlendirmesi ( John McCarthy'den sonra ), bazı programlama dillerinde ikinci argümanın yalnızca ilk argümanın değerini belirlemek için yeterli olmadığı durumlarda yürütüldüğü veya değerlendirildiği bazı Boole operatörlerinin semantiğidir. ifade: işlevin ilk argümanı olarak değerlendirildiğinde , genel değer şöyle olmalıdır ; ve işlevin ilk argümanı olarak değerlendirildiğinde , genel değer olmalıdır . ANDfalsefalseORtruetrue

Tembel değerlendirmeli programlama dillerinde ( Lisp , Perl , Haskell ), olağan Boole operatörleri kısa devredir. Diğerlerinde ( Ada , Java , Delphi ), hem kısa devre hem de standart Boole operatörleri mevcuttur. Özel veya (XOR) gibi bazı Boolean işlemleri için kısa devre yapmak mümkün değildir, çünkü sonucu belirlemek için her iki işlenen de her zaman gereklidir.

Kısa devre operatörleri, katı olmadıkları için basit aritmetik operatörlerden ziyade kontrol yapılarıdır . Olarak zorunlu dil açısından (özellikle Cı- ve C ++ yan etkiler önemlidir), kısa devre operatörler tanıtmak dizisi noktası - tamamen herhangi biri bulunan, birinci bağımsız değişken değerlendirmek yan etkiler ikinci değişkeni işleme (isteğe bağlı olarak) daha önce. Algol 68 kullanılan proceduring elde etmek için , kullanıcı tanımlı kısa devre operatörleri ve prosedürler.

Kısa devre operatörlerinin kullanımı sorunlu olarak eleştirilmiştir:

Koşullu bağlaçlar - kısaca " cand " ve " cor " - ilk bakışta göründüklerinden daha az masumdur. Örneğin, cor cand üzerinden dağıtmaz : karşılaştırın

(A cand B) korile (bir kor C) cand (B kor ° C);

¬A ∧ C durumunda, ikinci ifade B'nin tanımlanmasını gerektirir, birincisi gerektirmez. Koşullu bağlaçlar böylece programlarla ilgili biçimsel akıl yürütmeyi karmaşıklaştırdığından, bunlardan kaçınılması daha iyidir.

Tanım

Uygular kısa devre değerlendirme herhangi bir programlama dilinde, ekspresyon eşdeğerdir koşullu ifade ve ifade eşdeğerdir . Her iki durumda da x yalnızca bir kez değerlendirilir. x and y if x then y else xx or yif x then x else y

Yukarıdaki genelleştirilmiş tanım , kısa devre operatörlerinin en son değerlendirilen alt ifadeyi döndürebildiği, ikiden fazla doğruluk değerine sahip True ve False, gevşek yazılmış dilleri barındırır . Buna aşağıdaki tabloda "son değer" denir. Kesin olarak yazılan bir dil için, ifade boole durumu için ve sırasıyla basitleştirilir . if x then y else falseif x then true else y

Öncelik

Her ne kadar ANDsürer öncelik üzerinde ORbirçok dilde, bu kısa devre değerlendirmenin bir evrensel özellik değildir. Aynı önceliği alan ve birbiriyle sol ilişkisel olan iki operatörün bir örneği , POSIX kabuğunun komut listesi sözdizimidir.

Aşağıdaki basit soldan sağa değerlendirici bir öncelik zorlar ANDüzerinde ORbir yan continue:

function short-circuit-eval (operators, values)
    let result := True
    for each (op, val) in (operators, values):
        if op = "AND" && result = False
            continue
        else if op = "OR" && result = True
            return result
        else
            result := val
    return result

Resmileştirme

Yan etkileri olan veya olmayan kısa devre mantığı, Hoare'nin koşullu . Sonuç olarak, kısa devre yapmayan operatörler, aynı değerlendirme sırasına sahip olmak için kısa devre mantığı dışında tanımlanabilir.

Ortak programlama ve komut dosyası dillerinde destek

Çeşitli dillerde Boole operatörleri
Dilim hevesli operatörler Kısa devre operatörleri Sonuç türü
Gelişmiş İş Uygulama Programlama ( ABAP ) Yok and, or Boole 1
Ada and, or and then, or else Boole
ALGOL 68 ve, &, ∧ ; veya, ∨ andf , orf (her ikisi de kullanıcı tanımlı) Boole
APL , , (nand), (nor), vb. :AndIf, :OrIf Boole 1
awk Yok &&, || Boole
bash Yok &&, || Boole
C , Amaç-C Yok &&, ||,? int ( &&, ||), opnd bağımlı ( ?)
C++ 2 Yok &&, ||,? Boole ( &&, ||), opnd bağımlı ( ?)
C# &, | &&, ||, ?,?? Boole ( &&, ||), opnd bağımlı ( ?, ??)
ColdFusion İşaretleme Dili (CFML) Yok AND, OR, &&,|| Boole
D 3. &, | &&, ||,? Boole ( &&, ||), opnd bağımlı ( ?)
Eyfel and, or and then, or else Boole
Erlang and, or andalso, orelse Boole
Fortran 4 .and., .or. .and., .or. Boole
Git , Haskell , OCaml Yok &&, || Boole
Java , MATLAB , R , Swift &, | &&, || Boole
JavaScript , Julia &, | &&, || Son değer
Kement Yok and, or, &&,|| Son değer
Kotlin and, or &&, || Boole
Lisp , Lua , Şema Yok and, or Son değer
kabakulak (M) &, ! Yok sayısal
Modül-2 Yok AND, OR Boole
Oberon Yok &, OR Boole
OCaml Yok &&, || Boole
paskal and, or5 , 9 and_then, or_else6 , 9 Boole
Perl &, | &&, and, ||,or Son değer
yakut and, or &&, || Son değer
PHP &, | &&, and, ||,or Boole
POSIX kabuğu (komut listesi) Yok &&, || Son değer (çıkış)
piton Yok and, or Son değer
Pas &, | &&, || Boole
küçük konuşma &, | and:, or:7 Boole
standart makine öğrenimi Bilinmeyen andalso, orelse Boole
TTCN-3 Yok and, or Boole
Beckhoff TwinCAT® ( IEC 61131-3 ) 10 AND, OR AND_THEN, OR_ELSE Boole
Visual Basic .NET And, Or AndAlso, OrElse Boole
Visual Basic , Uygulamalar için Visual Basic (VBA) And, Or Select Case8 sayısal
Wolfram Dili And @@ {...}, Or @@ {...} And, Or, &&,|| Boole
ZTT &, | Yok Boole

1 ABAP ve APL'nin belirgin bir boole türü yoktur.
2 olduğunda aşırı , operatörler &&ve ||istekli ve herhangi bir tür geri dönebilir.
3 Bu yalnızca çalışma zamanı tarafından değerlendirilen ifadeler için geçerlidir static ifve static assert. Statik başlatıcılardaki veya bildirim sabitlerindeki ifadeler istekli değerlendirmeyi kullanır.
4 Fortran operatörleri ne kısa devrelidir ne de isteklidir: dil belirtimi derleyicinin optimizasyon yöntemini seçmesine izin verir.
5 ISO/IEC 10206:1990 Genişletilmiş Pascal , kısa devreye izin verir, ancak gerektirmez.
6 ISO/IEC 10206:1990 Genişletilmiş Pascal destekler and_thenve or_else.
7 Smalltalk, argümanı and:bir blok olduğu sürece (örneğin, false and: [Transcript show: 'Wont see me']) kısa devre semantiğini kullanır . CASE deyimlerini destekleyen
8 BASIC dili, bunu sabit etiketlerle sınırlı atlama tabloları yerine koşullu değerlendirme sistemini kullanarak yaptı.
9 Delphi ve Free Pascal varsayılan olarak kısa devre değerlendirmesi. Bu, derleyici seçenekleriyle değiştirilebilir ancak yaygın olarak kullanılmamaktadır.
10 standart IEC 61131-3 Aslında, eğer tanımlamaz ANDve ORkullanımı kısa devre değerlendirme ve operatörler tanımlamaz AND_THENve OR_ELSE. Tablodaki girişler, Beckhoff TwinCAT® için nasıl çalıştığını gösterir.

Genel kullanım

İkinci argümanın istenmeyen yan etkilerinden kaçınmak

C tabanlı bir dil kullanan olağan örnek :

int denom = 0;
if (denom != 0 && num / denom)
{
    ... // ensures that calculating num/denom never results in divide-by-zero error   
}

Aşağıdaki örneği göz önünde bulundurun:

int a = 0;
if (a != 0 && myfunc(b))
{
    do_something();
}

Bu örnekte, myfunc(b)asla çağrılmayan kısa devre değerlendirme garantileri . Bunun nedeni false olaraka != 0 değerlendirilmesidir . Bu özellik, iki kullanışlı programlama yapısına izin verir.

  1. İlk alt ifade pahalı bir hesaplamanın gerekip gerekmediğini kontrol ederse ve kontrol false olarak değerlendirilirse , ikinci argümanda pahalı hesaplama ortadan kaldırılabilir.
  2. İlk ifadenin, onsuz ikinci ifadenin bir çalışma zamanı hatasına neden olabileceği bir koşulu garanti ettiği bir yapıya izin verir .

Her ikisi de, minimum değerlendirmenin hem boş göstericinin kaldırılmasını hem de fazla bellek alımını önlediği aşağıdaki C parçacığında gösterilmektedir:

bool is_first_char_valid_alpha_unsafe(const char *p)
{
    return isalpha(p[0]); // SEGFAULT highly possible with p == NULL
}

bool is_first_char_valid_alpha(const char *p)
{
    return p != NULL && isalpha(p[0]); // 1) no unneeded isalpha() execution with p == NULL, 2) no SEGFAULT risk
}

Deyimsel koşullu yapı

Minimum değerlendirme bir operatörün semantik tanımının bir parçası olduğu ve (isteğe bağlı) bir optimizasyon olmadığı için , birçok kodlama modeli özlü (deyimsel ise) koşullu bir yapı olarak buna güvenmeye başlamıştır. Örnekler şunları içerir:

Perl deyimleri:

some_condition or die;    # Abort execution if some_condition is false
some_condition and die;   # Abort execution if some_condition is true

POSIX kabuk deyimleri:

modprobe -q some_module && echo "some_module installed" || echo "some_module not installed"

Bu deyim echobaşarısız olamayacağını varsayar .

Olası sorunlar

Test edilmemiş ikinci durum, gerçekleştirilmemiş yan etkiye yol açar

Bu faydalara rağmen, minimum değerlendirme, bunun gerçekleştiğini fark etmeyen (veya unutan) programcılar için sorunlara neden olabilir. Örneğin, kodda

if (expressionA && myfunc(b)) {
    do_something();
}

eğer myfunc(b)olursa olsun bazı gerekli işlemi gerçekleştirmek gerekiyordu do_something()böyle tahsis sistem kaynakları ve gibi yürütülür expressionAfalse ile değerlendirir, daha sonra myfunc(b)sorunlara neden olabilecek şekilde, yürütülmez. Java gibi bazı programlama dillerinde, bu sorunu önlemek için biri minimum değerlendirme kullanan ve diğeri kullanmayan iki operatör bulunur.

Gerçekleştirilmemiş yan etki ifadeleriyle ilgili sorunlar, uygun programlama stiliyle kolayca çözülebilir, yani, değerlendirmelerde yan etkileri olan değerlerin kullanılması genellikle kodu opak ve hataya açık hale getirme eğiliminde olduğundan, boole ifadelerinde yan etkilerin kullanılmaması gibi.

Kısıtlayıcı optimizasyonlar nedeniyle azaltılmış verimlilik

Kısa devre, modern merkezi işlem birimlerinde (CPU'lar) şube tahmininde hatalara yol açabilir ve performansı önemli ölçüde azaltabilir. Kayda değer bir örnek, ışın izlemede eksen hizalı kutu kesişim koduyla yüksek düzeyde optimize edilmiş ışındır . Bazı derleyiciler bu tür durumları algılayabilir ve daha hızlı kod yayınlayabilir, ancak programlama dili semantiği bu tür optimizasyonları sınırlayabilir.

Böyle bir durum için optimize edemeyen bir derleyici örneği , 2012 itibariyle Java'nın Hotspot VM'sidir.

Ayrıca bakınız

Referanslar