สิ่งที่ครูของคุณพูดคือคำพูดที่เอียง ๆ โดยไม่มีการชี้แจงมากนัก ไม่ใช่ว่าการลดจะเร็วกว่าการเพิ่ม แต่คุณสามารถสร้างลูปได้เร็วกว่ามากโดยมีการลดลงมากกว่าการเพิ่มขึ้น
โดยไม่ต้องใช้ความยาวโดยไม่จำเป็นต้องใช้ตัวนับลูป ฯลฯ สิ่งที่สำคัญด้านล่างนี้เป็นเพียงความเร็วและการนับลูป (ไม่ใช่ศูนย์)
นี่คือวิธีที่คนส่วนใหญ่ใช้การวนซ้ำ 10 ครั้ง:
int i;
for (i = 0; i < 10; i++)
{
}
สำหรับ 99% ของกรณีทั้งหมดอาจจำเป็นต้องใช้ แต่เมื่อรวมกับ PHP, PYTHON, JavaScript แล้วยังมีซอฟต์แวร์ที่สำคัญทั้งโลก (โดยปกติจะฝังตัว, OS, เกม ฯลฯ ) ที่ CPU เห็บมีความสำคัญมากดังนั้นให้ดูรหัสประกอบของ:
int i;
for (i = 0; i < 10; i++)
{
}
หลังจากคอมไพล์ (ไม่มีการปรับให้เหมาะสม) เวอร์ชันที่คอมไพล์อาจมีลักษณะเช่นนี้ (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:
ลูปทั้งหมดคือ 8 คำสั่ง (26 ไบต์) ในนั้น - มี 6 คำสั่ง (17 ไบต์) พร้อม 2 สาขา ใช่ใช่ฉันรู้ว่าทำได้ดีกว่านี้ (เป็นเพียงตัวอย่าง)
ลองพิจารณาโครงสร้างที่ใช้บ่อยซึ่งคุณมักจะพบว่าเขียนโดยนักพัฒนาที่ฝังตัว
i = 10;
do
{
} while (--i);
นอกจากนี้ยังวนซ้ำ 10 ครั้ง (ใช่ฉันรู้ว่าค่าของฉันแตกต่างกันเมื่อเทียบกับที่แสดงสำหรับลูป แต่เราสนใจเกี่ยวกับการนับการวนซ้ำที่นี่) สิ่งนี้อาจรวบรวมเป็นสิ่งนี้:
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 คำสั่ง (18 ไบต์) และเพียงสาขาเดียว จริงๆแล้วมี 4 คำสั่งในลูป (11 ไบต์)
สิ่งที่ดีที่สุดคือซีพียูบางตัว (รวมเข้ากันได้กับ x86 / x64) มีคำสั่งที่อาจลดรีจิสเตอร์จากนั้นเปรียบเทียบผลลัพธ์กับศูนย์และดำเนินการสาขาหากผลลัพธ์แตกต่างจากศูนย์ ซีพียูพีซีแทบทุกเครื่องใช้คำสั่งนี้ การใช้ลูปเป็นเพียงหนึ่งคำสั่ง (ใช่หนึ่ง) 2 ไบต์:
00144ECE B9 0A 00 00 00 mov ecx,0Ah
label:
00144ED3 E2 FE loop label (0144ED3h)
ฉันต้องอธิบายว่าอันไหนเร็วกว่า?
ตอนนี้แม้ว่า CPU บางตัวไม่ได้ใช้คำสั่งข้างต้นสิ่งที่จำเป็นในการเลียนแบบ แต่ก็เป็นการลดลงตามด้วยการกระโดดตามเงื่อนไขหากผลลัพธ์ของคำสั่งก่อนหน้าเป็นศูนย์
ดังนั้นไม่ว่าบางกรณีคุณอาจชี้ให้เห็นเป็นความคิดเห็นว่าทำไมฉันถึงทำผิด ฯลฯ ฉันยกระดับ - ใช่มันมีประโยชน์ที่จะวนลงถ้าคุณรู้วิธีทำไมและเมื่อไหร่
ปล. ใช่ฉันรู้ว่าคอมไพเลอร์ที่ชาญฉลาด (ที่มีระดับการเพิ่มประสิทธิภาพที่เหมาะสม) จะเขียนซ้ำสำหรับลูป (ที่มีตัวนับลูปจากน้อยไปหามาก) เป็น do .. ในขณะที่เทียบเท่ากับการวนซ้ำแบบคงที่ ... (หรือยกเลิกการเลื่อน) ...