เป็นเรื่องสำคัญที่จะไม่สร้างความสับสนให้กับข้อความสั่งสวิตช์ C # ด้วยคำสั่งสวิตช์ CIL
สวิตช์ CIL เป็นตารางการกระโดดที่ต้องการดัชนีในชุดของที่อยู่การกระโดด
สิ่งนี้มีประโยชน์ก็ต่อเมื่อกรณีของสวิตช์ C # อยู่ติดกัน:
case 3: blah; break;
case 4: blah; break;
case 5: blah; break;
แต่ใช้น้อยถ้าพวกเขาไม่ได้:
case 10: blah; break;
case 200: blah; break;
case 3000: blah; break;
(คุณต้องมีขนาดโต๊ะประมาณ 3000 รายการโดยใช้เพียง 3 ช่องเท่านั้น)
ด้วยนิพจน์ที่ไม่ติดกันคอมไพเลอร์อาจเริ่มทำการตรวจสอบเชิงเส้น if-else-if-else
คอมไพเลอร์อาจเริ่มต้นด้วยการค้นหาต้นไม้แบบไบนารีและสุดท้ายถ้า-else-if-else รายการสองสามรายการสุดท้าย
ด้วยชุดการแสดงออกที่มีกลุ่มของรายการที่อยู่ติดกันคอมไพเลอร์อาจค้นหาต้นไม้แบบไบนารีและในที่สุดก็เปลี่ยน CIL
นี่เต็มไปด้วย "mays" & "mights" และขึ้นอยู่กับคอมไพเลอร์ (อาจแตกต่างกับโมโนหรือโรเตอร์)
ฉันจำลองผลลัพธ์ของคุณบนเครื่องโดยใช้เคสที่อยู่ติดกัน:
เวลาทั้งหมดในการเรียกใช้สวิตช์ 10 ทาง, 10,000 รอบ (ms): 25.1383
เวลาโดยประมาณต่อสวิตช์ 10 ทาง (ms): 0.00251383
เวลาทั้งหมดในการเรียกใช้สวิตช์ 50 ทาง, 10,000 รอบ (ms): 26.593
เวลาโดยประมาณต่อสวิตช์ 50 ทาง (ms): 0.0026593
เวลาทั้งหมดในการเรียกใช้สวิตช์ 5000 ทาง, 10,000 รอบ (ms): 23.7094
เวลาโดยประมาณต่อสวิตช์ 5000 ทาง (มิลลิวินาที): 0.00237094
เวลาทั้งหมดในการเรียกใช้สวิตช์ 50000 วิธี, 10,000 ซ้ำ (มิลลิวินาที): 20.0933
เวลาโดยประมาณต่อสวิตช์ 50000 ทาง (มิลลิวินาที): 0.00200933
จากนั้นฉันก็ใช้นิพจน์ตัวพิมพ์เล็กและตัวพิมพ์เล็ก:
เวลาทั้งหมดในการเรียกใช้สวิตช์ 10 ทาง, 10,000 รอบ (ms): 19.6189
เวลาโดยประมาณต่อสวิตช์ 10 ทาง (ms): 0.00196189
เวลาทั้งหมดในการเรียกใช้สวิตช์ 500 ทาง, 10,000 รอบ (ms): 19.1664
เวลาโดยประมาณต่อสวิตช์ 500 ทาง (ms): 0.00191664
เวลาทั้งหมดในการเรียกใช้สวิตช์ 5000 ทาง, 10,000 รอบ (ms): 19.5871
เวลาโดยประมาณต่อสวิตช์ 5000 ทาง (ms): 0.00195871
คำสั่งสับเปลี่ยนกรณีขนาด 50,000 คำที่ไม่อยู่ติดกันจะไม่รวบรวม
"นิพจน์ยาวเกินไปหรือซับซ้อนเกินกว่าที่จะคอมไพล์ใกล้กับ 'ConsoleApplication1.Program.Main (string [])'
มีอะไรตลกที่นี่คือการค้นหาแบบต้นไม้ไบนารีจะเร็วกว่าการเรียนการสอนสวิตช์ CIL เล็กน้อย (อาจจะไม่เชิงสถิติ)
ไบรอันคุณใช้คำว่า " ค่าคงที่ " " ซึ่งมีความหมายที่ชัดเจนมากจากมุมมองของทฤษฎีความซับซ้อนในการคำนวณ ในขณะที่ตัวอย่างจำนวนเต็มที่อยู่ติดกันแบบง่าย ๆ อาจสร้าง CIL ซึ่งถือว่าเป็น O (1) (ค่าคงที่) แต่ตัวอย่างกระจัดกระจายคือ O (log n) (ลอการิทึม) ตัวอย่างกลุ่มที่อยู่ตรงกลางและตัวอย่างเล็ก ๆ คือ O (n) )
สิ่งนี้ไม่ได้ระบุถึงสถานการณ์ของ String ซึ่งGeneric.Dictionary<string,int32>
อาจสร้างแบบคงที่และจะได้รับค่าโสหุ้ยที่แน่นอนเมื่อใช้ครั้งแรก Generic.Dictionary
ผลการดำเนินงานที่นี่จะขึ้นอยู่กับประสิทธิภาพการทำงานของ
หากคุณตรวจสอบข้อกำหนดภาษา C # (ไม่ใช่ข้อมูลจำเพาะ CIL) คุณจะพบ "15.7.2 คำสั่ง switch" ไม่พูดถึง "เวลาคงที่" หรือการติดตั้งพื้นฐานนั้นยังใช้คำสั่ง CIL switch ด้วย (โปรดระวังอย่างมาก สิ่งต่าง ๆ )
ในตอนท้ายของวันสวิตช์ C # เทียบกับนิพจน์จำนวนเต็มในระบบที่ทันสมัยคือการดำเนินการย่อยไมโครวินาทีและโดยทั่วไปไม่น่ากังวล
แน่นอนเวลาเหล่านี้จะขึ้นอยู่กับเครื่องจักรและเงื่อนไข ฉันจะไม่ใส่ใจกับการทดสอบเวลาเหล่านี้ระยะเวลาไมโครวินาทีที่เรากำลังพูดถึงนั้นถูกแคระด้วยรหัส "ของจริง" ใด ๆ ที่กำลังทำงานอยู่ (และคุณต้องรวม "รหัสจริง" ไว้ไม่เช่นนั้นคอมไพเลอร์จะปรับสาขาออก) หรือ กระวนกระวายใจในระบบ คำตอบของฉันนั้นขึ้นอยู่กับการใช้IL DASMเพื่อตรวจสอบ CIL ที่สร้างโดยคอมไพเลอร์ C # แน่นอนว่านี่ไม่ใช่ขั้นตอนสุดท้ายเนื่องจากคำสั่งจริงที่ JIT สร้างขึ้นนั้นจะสร้างขึ้น
ฉันได้ตรวจสอบคำสั่ง CPU ขั้นสุดท้ายที่ดำเนินการจริงในเครื่อง x86 ของฉันและสามารถยืนยันสวิตช์ตั้งค่าที่อยู่ติดกันอย่างง่าย ๆ ที่ทำสิ่งต่าง ๆ เช่น:
jmp ds:300025F0[eax*4]
ตำแหน่งที่การค้นหาแบบต้นไม้ไบนารีเต็มไปด้วย:
cmp ebx, 79Eh
jg 3000352B
cmp ebx, 654h
jg 300032BB
…
cmp ebx, 0F82h
jz 30005EEE