Những gì giáo viên của bạn đã nói là một số tuyên bố xiên mà không làm rõ nhiều. KHÔNG phải là giảm dần nhanh hơn tăng nhưng bạn có thể tạo vòng lặp nhanh hơn nhiều với giảm dần so với tăng.
Không cần tiếp tục về nó, không cần sử dụng bộ đếm vòng lặp, v.v. - điều quan trọng dưới đây chỉ là tốc độ và số vòng lặp (khác không).
Đây là cách hầu hết mọi người thực hiện vòng lặp với 10 lần lặp:
int i;
for (i = 0; i < 10; i++)
{
//something here
}
Đối với 99% trường hợp, tất cả mọi người đều có thể cần, nhưng cùng với PHP, PYTHON, JavaScript, có cả thế giới phần mềm quan trọng về thời gian (thường được nhúng, HĐH, trò chơi, v.v.
int i;
for (i = 0; i < 10; i++)
{
//something here
}
sau khi biên dịch (không tối ưu hóa) phiên bản đã biên dịch có thể trông như thế này (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:
Toàn bộ vòng lặp là 8 hướng dẫn (26 byte). Trong đó - thực sự có 6 lệnh (17 byte) với 2 nhánh. Có, tôi biết nó có thể được thực hiện tốt hơn (nó chỉ là một ví dụ).
Bây giờ hãy xem xét cấu trúc thường xuyên này mà bạn sẽ thường thấy được viết bởi nhà phát triển nhúng:
i = 10;
do
{
//something here
} while (--i);
Nó cũng lặp lại 10 lần (vâng tôi biết giá trị của tôi khác so với hiển thị cho vòng lặp nhưng chúng tôi quan tâm đến số lần lặp ở đây). Điều này có thể được tổng hợp vào đây:
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 hướng dẫn (18 byte) và chỉ một nhánh. Thực tế có 4 lệnh trong vòng lặp (11 byte).
Điều tốt nhất là một số CPU (tương thích x86 / x64) có hướng dẫn có thể làm giảm thanh ghi, sau đó so sánh kết quả với 0 và thực hiện nhánh nếu kết quả khác 0. Hầu như TẤT CẢ PC cpus thực hiện hướng dẫn này. Sử dụng nó, vòng lặp thực sự chỉ là một (có một) lệnh 2 byte:
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
Tôi có phải giải thích cái nào nhanh hơn không?
Bây giờ ngay cả khi CPU cụ thể không thực hiện hướng dẫn trên, tất cả những gì nó yêu cầu để mô phỏng nó là một sự sụt giảm theo sau bước nhảy có điều kiện nếu kết quả của lệnh trước đó bằng không.
Vì vậy, bất kể một số trường hợp mà bạn có thể chỉ ra là một nhận xét tại sao tôi sai, v.v ... TÔI XÁC NHẬN - CÓ NÓ LÀ LỢI ÍCH ĐỂ LOOP TẢI XUỐNG nếu bạn biết cách, tại sao và khi nào.
Tái bút Có, tôi biết rằng trình biên dịch khôn ngoan (với mức tối ưu hóa phù hợp) sẽ viết lại cho vòng lặp (với bộ đếm vòng tăng dần) thành do..trong khi tương đương với các vòng lặp không đổi ... (hoặc hủy đăng ký nó) ...