ก่อนอื่น:
do-while
ห่วงไม่ได้เช่นเดียวกับwhile
-loop หรือfor
-loop
while
และfor
ลูปอาจไม่ทำงานในร่างกายของลูปเลย
do-while
ห่วงเสมอวิ่งร่างกายห่วงอย่างน้อยหนึ่งครั้ง - มันข้ามการตรวจสอบสภาวะเริ่มต้น
นั่นคือความแตกต่างเชิงตรรกะ ที่กล่าวว่าไม่ใช่ทุกคนที่ปฏิบัติตามอย่างเคร่งครัด เป็นเรื่องปกติที่จะใช้while
หรือfor
วนซ้ำแม้ว่าจะรับประกันว่าจะวนซ้ำอย่างน้อยหนึ่งครั้งเสมอ (โดยเฉพาะอย่างยิ่งในภาษาที่มีforeachลูป)
ดังนั้นเพื่อหลีกเลี่ยงการเปรียบเทียบแอปเปิ้ลกับส้มฉันจะดำเนินการต่อโดยสมมติว่าลูปจะทำงานอย่างน้อยหนึ่งครั้งเสมอ นอกจากนี้ฉันจะไม่พูดถึงfor
ลูปอีกเพราะโดยพื้นฐานแล้วwhile
ลูปนั้นมีน้ำตาลไวยากรณ์เล็กน้อยสำหรับตัวนับลูป
ดังนั้นฉันจะตอบคำถาม:
หากwhile
รับประกันการวนซ้ำอย่างน้อยหนึ่งครั้งจะมีประสิทธิภาพที่เพิ่มขึ้นจากการใช้do-while
ลูปแทนหรือไม่
do-while
ข้ามการตรวจสอบเงื่อนไขแรก ดังนั้นจึงมีสาขาน้อยกว่าหนึ่งสาขาและมีเงื่อนไขน้อยกว่าที่จะประเมิน
หากเงื่อนไขมีราคาแพงในการตรวจสอบและคุณรู้ว่าคุณรับประกันว่าจะวนซ้ำอย่างน้อยหนึ่งครั้งการdo-while
วนซ้ำอาจเร็วขึ้น
และแม้ว่านี่จะถือเป็นการเพิ่มประสิทธิภาพระดับไมโคร แต่ก็เป็นสิ่งที่คอมไพเลอร์ไม่สามารถทำได้เสมอไป: โดยเฉพาะอย่างยิ่งเมื่อคอมไพเลอร์ไม่สามารถพิสูจน์ได้ว่าลูปจะป้อนอย่างน้อยหนึ่งครั้งเสมอ
กล่าวอีกนัยหนึ่ง while-loop:
while (condition){
body
}
มีประสิทธิภาพเช่นเดียวกับสิ่งนี้:
if (condition){
do{
body
}while (condition);
}
หากคุณรู้ว่าคุณมักจะวนซ้ำอย่างน้อยหนึ่งครั้งคำสั่ง if นั้นไม่เกี่ยวข้อง
เช่นเดียวกันในระดับแอสเซมบลีนี่คือวิธีการที่ลูปต่างๆคอมไพล์เป็น:
ห่วงขณะทำ:
start:
body
test
conditional jump to start
ในขณะที่ห่วง:
test
conditional jump to end
start:
body
test
conditional jump to start
end:
โปรดทราบว่าเงื่อนไขซ้ำกัน แนวทางอื่นคือ:
unconditional jump to end
start:
body
end:
test
conditional jump to start
... ซึ่งแลกเปลี่ยนรหัสที่ซ้ำกันเพื่อการกระโดดเพิ่มเติม
ไม่ว่าจะด้วยวิธีใดก็ยังแย่กว่าการdo-while
วนซ้ำปกติ
กล่าวได้ว่าคอมไพเลอร์สามารถทำสิ่งที่ต้องการได้ และหากพวกเขาสามารถพิสูจน์ได้ว่าลูปเข้ามาเพียงครั้งเดียวแสดงว่ามันทำงานให้คุณแล้ว
แต่สิ่งที่ค่อนข้างแปลกสำหรับตัวอย่างเฉพาะในคำถามเพราะมีเนื้อหาวนซ้ำว่างเปล่า เนื่องจากมีร่างกายไม่ไม่มีความแตกต่างระหว่างตรรกะและwhile
do-while
FWIW ฉันทดสอบสิ่งนี้ใน Visual Studio 2012:
ด้วยร่างกายที่ว่างเปล่าก็ไม่จริงสร้างรหัสเดียวกันและwhile
do-while
ดังนั้นส่วนนั้นน่าจะเป็นสิ่งที่หลงเหลืออยู่ในสมัยก่อนที่คอมไพเลอร์ยังไม่ดีเท่า
แต่ด้วยร่างกายที่ไม่ว่างเปล่า VS2012 สามารถหลีกเลี่ยงการทำซ้ำรหัสเงื่อนไขได้ แต่ก็ยังสร้างการกระโดดตามเงื่อนไขเพิ่มเติม
ดังนั้นจึงเป็นเรื่องน่าขันที่แม้ว่าตัวอย่างในคำถามจะเน้นว่าเหตุใดการdo-while
วนซ้ำจึงเร็วกว่าในกรณีทั่วไป แต่ตัวอย่างนั้นดูเหมือนจะไม่ให้ประโยชน์ใด ๆ กับคอมไพเลอร์สมัยใหม่
เมื่อพิจารณาถึงความคิดเห็นนั้นเราสามารถเดาได้ว่าเหตุใดจึงมีความสำคัญ เป็นไปได้มากที่คอมไพเลอร์ในขณะนั้นไม่สามารถรับรู้ได้ว่าร่างกายว่างเปล่า (หรือถ้าเป็นเช่นนั้นก็ไม่ได้ใช้ข้อมูล)