Öğretmenin söylediği, çok fazla açıklama yapmadan dolaylı bir ifadeydi. Azaltmanın artmaktan daha hızlı olduğu DEĞİLDİR, ancak azaltma ile artıştan çok daha hızlı döngü oluşturabilirsiniz.
Bu konuda uzun uzadıya durmadan, döngü sayacı vb. Kullanmaya gerek kalmadan - aşağıda önemli olan sadece hız ve döngü sayısıdır (sıfır olmayan).
Çoğu insan 10 yinelemeli döngüyü şu şekilde uygular:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
Vakaların% 99'u için tek ihtiyaç duyulabilir ancak PHP, PYTHON, JavaScript ile birlikte, CPU işaretlerinin gerçekten önemli olduğu zaman açısından kritik yazılımlar (genellikle gömülü, işletim sistemi, oyunlar vb.) Vardır, bu nedenle kısaca montaj koduna bakın:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
derlemeden sonra (optimizasyon olmadan) derlenmiş sürüm şöyle görünebilir (VS2015):
-------- C7 45 B0 00 00 00 00 mov dword ptr [i],0
-------- EB 09 jmp labelB
labelA 8B 45 B0 mov eax,dword ptr [i]
-------- 83 C0 01 add eax,1
-------- 89 45 B0 mov dword ptr [i],eax
labelB 83 7D B0 0A cmp dword ptr [i],0Ah
-------- 7D 02 jge out1
-------- EB EF jmp labelA
out1:
Tüm döngü 8 talimattır (26 bayt). İçinde - aslında 2 dallı 6 talimat (17 bayt) var. Evet evet daha iyi yapılabileceğini biliyorum (bu sadece bir örnek).
Şimdi, genellikle gömülü geliştirici tarafından yazılmış bulacağınız bu sık yapıyı düşünün:
i = 10;
do
{
//something here
} while (--i);
Ayrıca 10 kez yinelenir (evet, değerin döngü için gösterilenle karşılaştırıldığında farklı olduğunu biliyorum, ancak burada yineleme sayısını önemsiyoruz). Bu, şu şekilde derlenebilir:
00074EBC C7 45 B0 01 00 00 00 mov dword ptr [i],1
00074EC3 8B 45 B0 mov eax,dword ptr [i]
00074EC6 83 E8 01 sub eax,1
00074EC9 89 45 B0 mov dword ptr [i],eax
00074ECC 75 F5 jne main+0C3h (074EC3h)
5 talimat (18 bayt) ve sadece bir dal. Aslında döngüde 4 komut vardır (11 bayt).
En iyisi, bazı CPU'ların (x86 / x64 uyumlu dahil) bir kaydı azaltan, daha sonra sonucu sıfırla karşılaştıran ve sonuç sıfırdan farklıysa dallanma gerçekleştiren talimatlara sahip olmasıdır. Neredeyse TÜM PC CPU'lar bu talimatı uygular. Bunu kullanarak döngü aslında sadece bir (evet bir) 2 baytlık talimattır:
00144ECE B9 0A 00 00 00 mov ecx,0Ah
label:
// something here
00144ED3 E2 FE loop label (0144ED3h) // decrement ecx and jump to label if not zero
Hangisinin daha hızlı olduğunu açıklamam gerekiyor mu?
Şimdi, belirli bir CPU yukarıdaki talimatı uygulamasa bile, bunu taklit etmek için gereken tek şey bir azalmadır ve önceki talimatın sonucu sıfır olursa koşullu atlamadır.
Öyleyse, bazı durumlardan bağımsız olarak, neden yanıldığımı vb. Bir yorum olarak gösterebilirsiniz. VURUŞUYORUM - EVET, nasıl, neden ve ne zaman olduğunu biliyorsanız, DÜŞÜRMEK FAYDALIDIR.
PS. Evet, bilge derleyicinin (uygun optimizasyon düzeyine sahip) döngü için yeniden yazacağını (artan döngü sayacı ile) do'ya yeniden yazacağını biliyorum, bu arada sabit döngü yinelemeleri için eşdeğer ... (veya kaydı sil) ...