Merhaba,
Geçen hafta Talha, dizilerin ilk elemanına işaretçi ile erişirken hızlı olduğunu, yasal bir şekilde köşeli parantez içinde [0] yazarak erişirken ise yavaş kaldığını tespit etmişti...
Sonra bunun assembly koduna baktık ve gördük ki:
Her ne yaparsak yapalım bu şekilde yasal kullanımlarda 'core.exception.RangeError' (assembly'de _D2as7__arrayZ) sınıfının denetlemesine ve/veya hata kodunu atmasına mağruz kalıyoruz. Madem öyle, aşağıdaki gibi kullandığımızda (nedense Exception'da yakalayamadım, Throwable kullandım) kodu kısaltmanız mümkün:
import std.stdio;
void main() {
size_t[] dizi = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
size_t sayaç;
bool devam = true;
Alıntı:
>> do {
> try {
> dizi[sayaç++].writeln();
> } catch (Throwable hata) {
> devam = false;
> }
> } while(devam);
> }
> ```
>
Yukarıdaki kodun assembly karşılığı aşağıda; ama sadece döngü kümesi:
Alıntı:
> '
> L70: '; do {'
> mov ESI,-0Ch[EBP] '; ESI <- sayaç'
> inc dword ptr -0Ch[EBP] '; sayaç++'
> cmp ESI,-014h[EBP] '; CarryFlag == True ise taşma var!'
> jb L85
> mov EAX,0Bh
> call _D2as7__arrayZ@PC32
> L85:
> mov EDX,-010h[EBP] '; ECX <- sayaç'
> mov EAX,-014h[EBP] '; EAX <- dizi.length'
> mov EAX,[ESI*4][EDX] '; EAX <- dizi[sayaç]'
> call _D3std5stdio14__T7writelnTkZ7writelnFkZv@PC32
> jmp short L99
> mov byte ptr -8[EBP],0 '; devam == false'
> L99: '; } while(devam);'
> cmp byte ptr -8[EBP],0
> jne L70'
>
Bu kodda, taşma olması durumunda **L99** etiketine atlayarak program göçmeden sonlanmasını sağlıyoruz. Eğer **try/catch** kümesini kaldırıp basit bir 'if()' koşulu ile benzer şeyi yaparsak şu değişiklikler oluyor:
Alıntı:
>
>
> do {
dizi[sayaç++].writeln();
if(sayaç == dizi.length) devam = false;
} while(devam);
>
Önceki assembly koduna çok benzemekte!
Alıntı:
>'
L70: '; do {'
mov ESI,-0Ch[EBP]
inc dword ptr -0Ch[EBP]
cmp ESI,-014h[EBP]
jb L85
mov EAX,0Bh
call _D2as7__arrayZ@PC32
L85:
mov EDX,-0Ch[EBP] '; EDX <- sayaç'
mov EAX,-014h[EBP] '; EAX <- dizi.length'
mov EAX,[ESI*4][EDX]
call _D3std5stdio14__T7writelnTkZ7writelnFkZv@PC32
mov ECX,-0Ch[EBP] '; ECX <- sayaç'
cmp ECX,-014h[EBP] '; ZeroFlag == False ise eşitler!'
jne L99
mov byte ptr -8[EBP],0 '; devam == false'
L99: '; } while(devam);'
cmp byte ptr -8[EBP],0
jne L70'
Peki sizce ilk kodda try/catch hatayı nasıl yakalıyor olabilir? Normalde hatayı atan alt yordam _D2as7__arrayZ, ekrana yazı yazan ise _D3std5stdio14__T7writelnTkZ7writelnFkZv harici işlevi. Bir şekilde 'jne L99' satırını atlıyor olmalı ki döngü sonlansın.
Başarılar...
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]