โดยทั่วไปคำสั่ง Switch จะเร็วกว่าคำสั่ง if-else-if ที่เทียบเท่า (เช่นอธิบายไว้ในบทความนี้ ) เนื่องจากการปรับแต่งคอมไพลเลอร์
การเพิ่มประสิทธิภาพนี้ทำงานอย่างไร ใครมีคำอธิบายดีๆ
โดยทั่วไปคำสั่ง Switch จะเร็วกว่าคำสั่ง if-else-if ที่เทียบเท่า (เช่นอธิบายไว้ในบทความนี้ ) เนื่องจากการปรับแต่งคอมไพลเลอร์
การเพิ่มประสิทธิภาพนี้ทำงานอย่างไร ใครมีคำอธิบายดีๆ
คำตอบ:
คอมไพเลอร์สามารถสร้างตารางกระโดดได้หากมี ตัวอย่างเช่นเมื่อคุณใช้ตัวสะท้อนแสงเพื่อดูโค้ดที่สร้างขึ้นคุณจะเห็นว่าสำหรับสวิตช์ขนาดใหญ่บนสตริงคอมไพเลอร์จะสร้างโค้ดที่ใช้ตารางแฮชเพื่อส่งสิ่งเหล่านี้ ตารางแฮชใช้สตริงเป็นคีย์และมอบหมายให้case
โค้ดเป็นค่า
สิ่งนี้มีรันไทม์ที่ไม่แสดงอาการดีกว่าif
การทดสอบแบบล่ามโซ่จำนวนมากและเร็วกว่าแม้ว่าจะมีสตริงที่ค่อนข้างน้อยก็ตาม
นี่เป็นการทำให้ง่ายขึ้นเล็กน้อยตามปกติแล้วคอมไพเลอร์สมัยใหม่ใด ๆ ที่พบif..else if ..
ลำดับที่สามารถแปลงเป็นคำสั่งสวิตช์โดยบุคคลได้เล็กน้อยคอมไพเลอร์ก็เช่นกัน แต่เพื่อเพิ่มความสนุกเป็นพิเศษคอมไพลเลอร์ไม่ได้ถูก จำกัด ด้วยไวยากรณ์ดังนั้นจึงสามารถสร้าง "สวิตช์" เช่นเดียวกับคำสั่งภายในที่มีการผสมผสานของช่วงเป้าหมายเดียว ฯลฯ - และพวกเขาสามารถ (และทำ) ทำสิ่งนี้ได้สำหรับทั้งสวิตช์และ if .else งบ
Anyhoo ส่วนขยายของคำตอบของ Konrad คือคอมไพเลอร์อาจสร้างตารางการกระโดด แต่ก็ไม่จำเป็นต้องรับประกัน (หรือเป็นที่ต้องการ) ด้วยเหตุผลหลายประการตารางการกระโดดทำให้เกิดสิ่งที่ไม่ดีกับตัวทำนายสาขาในโปรเซสเซอร์สมัยใหม่และตารางเองก็ทำสิ่งที่ไม่ดีต่อพฤติกรรมแคชเช่น
switch(a) { case 0: ...; break; case 1: ...; break; }
หากคอมไพเลอร์สร้างตารางกระโดดสำหรับสิ่งนี้จริง ๆ ก็น่าจะช้ากว่าที่if..else if..
โค้ดรูปแบบทางเลือกเนื่องจากตารางกระโดดที่เอาชนะการทำนายสาขา
สถิติที่ไม่ตรงกันอาจไม่ดี
หากคุณดาวน์โหลดแหล่งที่มาจริง ๆ ค่าที่ไม่ตรงกันจะเป็น 21 ทั้งในกรณี if และ switch คอมไพเลอร์ควรสามารถสรุปได้โดยรู้ว่าคำสั่งใดควรถูกเรียกใช้ตลอดเวลาและซีพียูควรจะสามารถแยกการทำนายได้อย่างถูกต้อง
กรณีที่น่าสนใจกว่าคือเมื่อไม่ใช่ทุกกรณีในความคิดของฉัน แต่นั่นอาจไม่ใช่ขอบเขตของการทดลอง
คำสั่ง Switch / case อาจเร็วกว่า 1 ระดับลึก แต่เมื่อคุณเริ่มเข้าสู่ 2 หรือมากกว่าคำสั่ง switch / case จะเริ่มใช้เวลา 2-3 เท่าตราบเท่าที่คำสั่ง if / else แบบซ้อนกัน
บทความนี้มีการเปรียบเทียบความเร็วบางส่วนที่เน้นความแตกต่างของความเร็วเมื่อข้อความดังกล่าวซ้อนกัน
ตัวอย่างเช่นตามการทดสอบของพวกเขาตัวอย่างโค้ดดังต่อไปนี้:
if (x % 3 == 0)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 1)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 2)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
เสร็จสิ้นในครึ่งเวลาที่คำสั่ง switch / case ที่เทียบเท่าใช้ในการรัน:
switch (x % 3)
{
case 0:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
case 1:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
case 2:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
default:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
}
ใช่มันเป็นตัวอย่างพื้นฐาน แต่มันแสดงให้เห็นถึงประเด็น
ดังนั้นข้อสรุปอาจใช้สวิตช์ / กรณีสำหรับประเภทง่ายๆที่ลึกเพียงระดับเดียว แต่สำหรับการเปรียบเทียบที่ซับซ้อนมากขึ้นและระดับซ้อนกันหลายระดับให้ใช้การสร้าง if / else แบบคลาสสิก?
ข้อดีอย่างเดียวของ if over case คือเมื่อมีความถี่ในการเกิดกรณีแรกเพิ่มขึ้นอย่างเห็นได้ชัด
ไม่แน่ใจว่าธรณีประตูอยู่ตรงไหน แต่ฉันใช้ case syntax เว้นแต่ว่า "เกือบตลอดเวลา" แรกจะผ่านการทดสอบครั้งแรก