ความแตกต่างของประสิทธิภาพสัมพัทธ์ของคำสั่ง if / else กับ switch ใน Java คืออะไร?


124

กังวลเกี่ยวกับประสิทธิภาพของเว็บแอปพลิเคชันของฉันฉันสงสัยว่าคำสั่ง "if / else" หรือคำสั่ง switch ใดดีกว่าสำหรับประสิทธิภาพ


6
คุณมีเหตุผลใดที่คิดว่ารหัสไบต์เดียวกันไม่ได้ถูกสร้างขึ้นสำหรับโครงสร้างทั้งสอง
Pascal Cuoq

2
@Pascal: อาจมีการเพิ่มประสิทธิภาพโดยใช้การค้นหาตารางแทนรายการifฯลฯ
jldupont

18
"การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากเหง้าของความชั่วร้ายทั้งหมด" - Donald Knuth
missingfaktor

104
แม้ว่านี่จะเป็นการเพิ่มประสิทธิภาพก่อนเวลาอันควรอย่างแน่นอน "การยึดมั่นในคำพูดที่ไม่เหมาะสมกับบริบทคือเหตุผลที่เราต้องการคอมพิวเตอร์มัลติคอร์ระดับไฮเอนด์เพียงเพื่อแสดง GUI ที่ตอบสนองอย่างสมเหตุสมผลในวันนี้" - ฉัน
Lawrence Dol

2
Knuth มีจิตใจที่แม่นยำ โปรดสังเกตรอบคัดเลือก "ก่อนกำหนด" การเพิ่มประสิทธิภาพเป็นข้อกังวลที่ถูกต้องอย่างสมบูรณ์ ที่กล่าวว่าเซิร์ฟเวอร์ถูกผูกไว้กับ IO และปัญหาคอขวดของเครือข่ายและดิสก์ I / O เป็นลำดับความสำคัญมากกว่าสิ่งอื่นใดที่คุณเกิดขึ้นในเซิร์ฟเวอร์ของคุณ
alphazero

คำตอบ:


108

นั่นคือการเพิ่มประสิทธิภาพขนาดเล็กและการเพิ่มประสิทธิภาพก่อนกำหนดซึ่งเป็นสิ่งที่ชั่วร้าย ค่อนข้างกังวลเกี่ยวกับความสามารถในการอ่านและการบำรุงรักษาของโค้ดที่เป็นปัญหา หากมีif/elseบล็อกมากกว่าสองบล็อกที่ติดกาวเข้าด้วยกันหรือขนาดของบล็อกไม่สามารถคาดเดาได้คุณอาจพิจารณาswitchคำแถลงดังกล่าว

หรือคุณยังสามารถคว้าPolymorphism ก่อนอื่นให้สร้างส่วนต่อประสาน:

public interface Action { 
    void execute(String input);
}

Mapและได้รับถือของการใช้งานในบางส่วน คุณสามารถทำได้ทั้งแบบคงที่หรือแบบไดนามิก:

Map<String, Action> actions = new HashMap<String, Action>();

สุดท้ายแทนที่if/elseหรือswitchด้วยสิ่งนี้ (ปล่อยการตรวจสอบเล็กน้อยเช่น nullpointers ไว้ข้างๆ):

actions.get(name).execute(input);

มันอาจจะไมโครช้ากว่าif/elseหรือswitchแต่อย่างน้อยรหัสก็สามารถบำรุงรักษาได้ดีกว่ามาก

ในขณะที่คุณกำลังพูดถึงแอปพลิเคชันบนเว็บคุณสามารถใช้HttpServletRequest#getPathInfo()เป็นคีย์การดำเนินการได้ (ในที่สุดก็เขียนโค้ดเพิ่มเติมเพื่อแยกส่วนสุดท้ายของ pathinfo ออกไปในวงรอบจนกว่าจะพบการดำเนินการ) คุณสามารถหาคำตอบที่คล้ายกันได้ที่นี่:

หากคุณกังวลเกี่ยวกับประสิทธิภาพของโปรแกรมประยุกต์บนเว็บ Java EE โดยทั่วไปคุณอาจพบว่าบทความนี้มีประโยชน์เช่นกัน มีพื้นที่อื่น ๆ ซึ่งจะช่วยให้มีมากขึ้นได้รับประสิทธิภาพกว่าเท่านั้น (ไมโคร) การเพิ่มประสิทธิภาพรหัส Java ดิบ


1
หรือพิจารณาความหลากหลายแทน
jk.

แนะนำให้ใช้มากกว่านี้ในกรณีที่มีการบล็อก if / else ที่ "คาดเดาไม่ได้"
BalusC

73
ฉันไม่ด่วนสรุปว่าการเพิ่มประสิทธิภาพในช่วงต้นทั้งหมดเป็น "ชั่วร้าย" การก้าวร้าวเกินไปเป็นเรื่องโง่เขลา แต่เมื่อต้องเผชิญกับโครงสร้างของความสามารถในการอ่านเทียบเคียงการเลือกสิ่งที่รู้ว่าทำงานได้ดีกว่าเป็นการตัดสินใจที่เหมาะสม
Brian Knoblauch

8
เวอร์ชันการค้นหา HashMap อาจช้าลง 10 เท่าเมื่อเทียบกับคำสั่ง tablewitsch ฉันจะไม่เรียกสิ่งนี้ว่า "ไมโครโบลเวอร์"!
x4u

7
ฉันสนใจที่จะรู้จริง ๆ เกี่ยวกับการทำงานภายในของ Java ในกรณีทั่วไปที่มีคำสั่ง switch - ฉันไม่สนใจว่าจะมีใครคิดว่าสิ่งนี้เกี่ยวข้องกับการจัดลำดับความสำคัญสูงเกินไปหรือไม่ ดังที่กล่าวมาฉันไม่รู้เลยว่าทำไมคำตอบนี้ถึงได้รับการโหวตมากขนาดนี้และเหตุใดจึงเป็นคำตอบที่ยอมรับ ... สิ่งนี้ไม่ได้ตอบคำถามเริ่มต้น
Searchengine27

125

ฉันเห็นด้วยอย่างยิ่งกับความคิดเห็นที่ว่าการเพิ่มประสิทธิภาพก่อนกำหนดเป็นสิ่งที่ควรหลีกเลี่ยง

แต่เป็นความจริงที่ Java VM มี bytecodes พิเศษซึ่งสามารถใช้สำหรับ switch () ได้

ดูข้อมูลจำเพาะ WM ( สวิตช์การค้นหาและสวิตช์ตาราง )

ดังนั้นจึงอาจมีการเพิ่มประสิทธิภาพบางอย่างหากโค้ดเป็นส่วนหนึ่งของกราฟประสิทธิภาพของ CPU


60
ฉันสงสัยว่าทำไมความคิดเห็นนี้ถึงไม่ได้รับการจัดอันดับสูงกว่านี้: เป็นข้อมูลที่ให้ข้อมูลมากที่สุดสำหรับพวกเขาทั้งหมด ฉันหมายถึง: เราทุกคนรู้อยู่แล้วว่าการปรับให้เหมาะสมก่อนเวลาอันควรเป็นสิ่งที่ไม่ดีและไม่จำเป็นต้องอธิบายว่าเป็นครั้งที่ 1000
Folkert van Heusden

5
+1 ณstackoverflow.com/a/15621602/89818ดูเหมือนว่าประสิทธิภาพจะเพิ่มขึ้นจริงๆและคุณควรเห็นข้อได้เปรียบหากคุณใช้ 18+ เคส
caw

52

ไม่น่าเป็นไปได้อย่างยิ่งที่ if / else หรือสวิตช์จะเป็นสาเหตุของปัญหาด้านประสิทธิภาพของคุณ หากคุณมีปัญหาด้านประสิทธิภาพคุณควรทำการวิเคราะห์โปรไฟล์ประสิทธิภาพก่อนเพื่อพิจารณาว่าจุดที่ช้าอยู่ตรงไหน การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นต้นตอของความชั่วร้ายทั้งหมด!

อย่างไรก็ตามเป็นไปได้ที่จะพูดถึงประสิทธิภาพสัมพัทธ์ของสวิตช์เทียบกับ if / else ด้วยการปรับแต่งคอมไพเลอร์ Java ก่อนอื่นโปรดทราบว่าใน Java คำสั่ง switch ทำงานบนโดเมนที่ จำกัด มาก - จำนวนเต็ม โดยทั่วไปคุณสามารถดูคำสั่ง switch ได้ดังนี้:

switch (<condition>) {
   case c_0: ...
   case c_1: ...
   ...
   case c_n: ...
   default: ...
}

โดยที่c_0, c_1... และc_Nเป็นตัวเลขหนึ่งที่เป็นเป้าหมายของคำสั่ง switch และ<condition>ต้องแก้ไขเป็นนิพจน์จำนวนเต็ม

  • ถ้าชุดนี้ "หนาแน่น" นั่นคือ (max (c i ) + 1 - min (c i )) / n> αโดยที่ 0 <k <α <1 โดยที่kมากกว่าค่าเชิงประจักษ์บางค่า a สามารถสร้างตารางกระโดดซึ่งมีประสิทธิภาพสูง

  • หากชุดนี้ไม่หนาแน่นมาก แต่ n> = βต้นไม้ค้นหาแบบไบนารีสามารถค้นหาเป้าหมายได้ใน O (2 * log (n)) ซึ่งยังคงมีประสิทธิภาพเช่นกัน

สำหรับกรณีอื่น ๆ ทั้งหมดคำสั่ง switch มีประสิทธิภาพเท่ากับชุดคำสั่ง if / else ที่เทียบเท่ากัน ค่าที่แม่นยำของαและβขึ้นอยู่กับปัจจัยหลายประการและกำหนดโดยโมดูลการเพิ่มประสิทธิภาพโค้ดของคอมไพเลอร์

ในที่สุดถ้าโดเมนของ<condition>ไม่ใช่จำนวนเต็มคำสั่ง switch ก็ไร้ประโยชน์อย่างสิ้นเชิง


+1 มีโอกาสที่ดีที่เวลาที่ใช้กับ I / O เครือข่ายจะบดบังปัญหานี้ได้อย่างง่ายดาย
Adam Paynter

3
ควรสังเกตว่าสวิตช์ทำงานร่วมกับ ints มากกว่า จากบทช่วยสอน Java: "สวิตช์ทำงานกับชนิดข้อมูลไบต์สั้นถ่านและ int primitive นอกจากนี้ยังใช้งานได้กับประเภทที่แจกแจง (กล่าวถึงในประเภท Enum) คลาส String และคลาสพิเศษบางประเภทที่รวมประเภทดั้งเดิมบางประเภท : Character, Byte, Short และ Integer (กล่าวถึงใน Numbers and Strings) " การสนับสนุน String คือการเพิ่มล่าสุด เพิ่มใน Java 7. docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
atraudes

1
@jhonFeminella คุณช่วยเปรียบเทียบ BIG O notion effects สำหรับ Java7 String ใน Swtich เทียบกับ String ใน if / else if .. ?
Kanagavelu Sugumar

แม่นยำยิ่งขึ้น javac 8 ให้น้ำหนัก 3 ต่อความซับซ้อนของเวลาเหนือความซับซ้อนของอวกาศ: stackoverflow.com/a/31032054/895245
Ciro Santilli 郝海东冠状病六四事件法轮功

11

ใช้สวิตช์!

ฉันเกลียดที่จะรักษา if-else-blocks! มีการทดสอบ:

public class SpeedTestSwitch
{
    private static void do1(int loop)
    {
        int temp = 0;
        for (; loop > 0; --loop)
        {
            int r = (int) (Math.random() * 10);
            switch (r)
            {
                case 0:
                    temp = 9;
                    break;
                case 1:
                    temp = 8;
                    break;
                case 2:
                    temp = 7;
                    break;
                case 3:
                    temp = 6;
                    break;
                case 4:
                    temp = 5;
                    break;
                case 5:
                    temp = 4;
                    break;
                case 6:
                    temp = 3;
                    break;
                case 7:
                    temp = 2;
                    break;
                case 8:
                    temp = 1;
                    break;
                case 9:
                    temp = 0;
                    break;
            }
        }
        System.out.println("ignore: " + temp);
    }

    private static void do2(int loop)
    {
        int temp = 0;
        for (; loop > 0; --loop)
        {
            int r = (int) (Math.random() * 10);
            if (r == 0)
                temp = 9;
            else
                if (r == 1)
                    temp = 8;
                else
                    if (r == 2)
                        temp = 7;
                    else
                        if (r == 3)
                            temp = 6;
                        else
                            if (r == 4)
                                temp = 5;
                            else
                                if (r == 5)
                                    temp = 4;
                                else
                                    if (r == 6)
                                        temp = 3;
                                    else
                                        if (r == 7)
                                            temp = 2;
                                        else
                                            if (r == 8)
                                                temp = 1;
                                            else
                                                if (r == 9)
                                                    temp = 0;
        }
        System.out.println("ignore: " + temp);
    }

    public static void main(String[] args)
    {
        long time;
        int loop = 1 * 100 * 1000 * 1000;
        System.out.println("warming up...");
        do1(loop / 100);
        do2(loop / 100);

        System.out.println("start");

        // run 1
        System.out.println("switch:");
        time = System.currentTimeMillis();
        do1(loop);
        System.out.println(" -> time needed: " + (System.currentTimeMillis() - time));

        // run 2
        System.out.println("if/else:");
        time = System.currentTimeMillis();
        do2(loop);
        System.out.println(" -> time needed: " + (System.currentTimeMillis() - time));
    }
}

รหัสมาตรฐาน C # ของฉันสำหรับการเปรียบเทียบ


คุณช่วยอธิบายรายละเอียดเล็กน้อยเกี่ยวกับวิธีที่คุณทำเกณฑ์มาตรฐานนี้ได้หรือไม่?
DerMike

ขอบคุณมากสำหรับการอัปเดตของคุณ ฉันหมายความว่ามันแตกต่างกันตามลำดับความสำคัญ - ซึ่งเป็นไปได้แน่นอน คุณแน่ใจหรือว่าคอมไพเลอร์ไม่ได้เพิ่มประสิทธิภาพswitches ออกไปเท่านั้น
DerMike

@DerMike ฉันจำไม่ได้ว่าฉันได้ผลลัพธ์เก่าอย่างไร วันนี้ฉันแตกต่างกันมาก แต่ลองด้วยตัวเองและแจ้งให้เราทราบว่ามันเป็นอย่างไร
Bitterblue

1
เมื่อฉันใช้งานบนแล็ปท็อปของฉัน เปลี่ยนเวลาที่ต้องการ: 3585 ถ้า / อื่นเวลาที่ต้องการ: 3458 ดังนั้นถ้า / else ดีกว่า :) หรือไม่แย่กว่านั้น
halil

1
ต้นทุนที่โดดเด่นในการทดสอบคือการสร้างตัวเลขแบบสุ่ม ฉันแก้ไขการทดสอบเพื่อสร้างตัวเลขสุ่มก่อนลูปและใช้ค่า temp เพื่อป้อนกลับเป็น r จากนั้นสวิตช์จะเร็วกว่าโซ่ if-else เกือบสองเท่า
boneill

8

ฉันจำได้ว่าเคยอ่านว่ามีคำสั่ง Switch 2 ประเภทใน bytecode ของ Java (ฉันคิดว่ามันอยู่ใน 'Java Performance Tuning' หนึ่งคือการใช้งานที่รวดเร็วมากซึ่งใช้ค่าจำนวนเต็มของคำสั่ง switch เพื่อให้ทราบถึง offset ของโค้ดที่จะดำเนินการสิ่งนี้ต้องการให้จำนวนเต็มทั้งหมดติดต่อกันและอยู่ในช่วงที่กำหนดไว้อย่างดี ฉันเดาว่าการใช้ค่าทั้งหมดของ Enum จะอยู่ในประเภทนั้นด้วย

ฉันเห็นด้วยกับโปสเตอร์อื่น ๆ อีกมากมายแม้ว่า ... อาจเป็นเรื่องที่ต้องกังวลก่อนเวลาอันควรเว้นแต่นี่จะเป็นรหัสที่ร้อนแรงมาก


4
+1 สำหรับความคิดเห็นรหัสร้อน ถ้ามันอยู่ในลูปหลักของคุณมันไม่เกิดก่อนกำหนด
KingAndrew

ใช่javacใช้switchหลายวิธีบางอย่างมีประสิทธิภาพมากกว่าวิธีอื่น ๆ โดยทั่วไปประสิทธิภาพจะไม่เลวร้ายไปกว่า " ifบันได" ตรงไปตรงมาแต่มีรูปแบบต่างๆเพียงพอ (โดยเฉพาะกับ JITC) ที่ยากที่จะแม่นยำกว่านั้นมาก
Hot Licks

8

อ้างอิงจาก Cliff Click ในปี 2009 Java One talk A Crash Course in Modern Hardware :

ทุกวันนี้ประสิทธิภาพถูกครอบงำด้วยรูปแบบการเข้าถึงหน่วยความจำ แคชพลาดครอบงำ - หน่วยความจำคือดิสก์ใหม่ [สไลด์ 65]

คุณจะได้รับภาพนิ่งเต็มของเขาที่นี่

คลิฟยกตัวอย่าง (จบในสไลด์ 30) ที่แสดงให้เห็นว่าแม้ซีพียูจะทำการเปลี่ยนชื่อการลงทะเบียนการทำนายสาขาและการดำเนินการแบบเก็งกำไร แต่ก็สามารถเริ่มการดำเนินการได้ 7 ครั้งใน 4 รอบนาฬิกาก่อนที่จะต้องบล็อกเนื่องจากแคชสองตัวที่พลาด300รอบนาฬิกาเพื่อย้อนกลับ

ดังนั้นเขาจึงบอกว่าให้เร่งโปรแกรมของคุณคุณไม่ควรมองไปที่ปัญหาเล็กน้อยประเภทนี้ แต่ในประเด็นที่ใหญ่กว่าเช่นคุณกำลังทำการแปลงรูปแบบข้อมูลที่ไม่จำเป็นหรือไม่เช่นการแปลง "SOAP → XML → DOM → SQL → ... "ซึ่ง" ส่งผ่านข้อมูลทั้งหมดผ่านแคช "


4

ในการทดสอบของฉันประสิทธิภาพที่ดีขึ้นคือENUM> MAP> SWITCH> IF / ELSE IFใน Windows7

import java.util.HashMap;
import java.util.Map;

public class StringsInSwitch {
public static void main(String[] args) {
    String doSomething = null;


    //METHOD_1 : SWITCH
    long start = System.currentTimeMillis();
    for (int i = 0; i < 99999999; i++) {
        String input = "Hello World" + (i & 0xF);

        switch (input) {
        case "Hello World0":
            doSomething = "Hello World0";
            break;
        case "Hello World1":
            doSomething = "Hello World0";
            break;
        case "Hello World2":
            doSomething = "Hello World0";
            break;
        case "Hello World3":
            doSomething = "Hello World0";
            break;
        case "Hello World4":
            doSomething = "Hello World0";
            break;
        case "Hello World5":
            doSomething = "Hello World0";
            break;
        case "Hello World6":
            doSomething = "Hello World0";
            break;
        case "Hello World7":
            doSomething = "Hello World0";
            break;
        case "Hello World8":
            doSomething = "Hello World0";
            break;
        case "Hello World9":
            doSomething = "Hello World0";
            break;
        case "Hello World10":
            doSomething = "Hello World0";
            break;
        case "Hello World11":
            doSomething = "Hello World0";
            break;
        case "Hello World12":
            doSomething = "Hello World0";
            break;
        case "Hello World13":
            doSomething = "Hello World0";
            break;
        case "Hello World14":
            doSomething = "Hello World0";
            break;
        case "Hello World15":
            doSomething = "Hello World0";
            break;
        }
    }

    System.out.println("Time taken for String in Switch :"+ (System.currentTimeMillis() - start));




    //METHOD_2 : IF/ELSE IF
    start = System.currentTimeMillis();

    for (int i = 0; i < 99999999; i++) {
        String input = "Hello World" + (i & 0xF);

        if(input.equals("Hello World0")){
            doSomething = "Hello World0";
        } else if(input.equals("Hello World1")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World2")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World3")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World4")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World5")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World6")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World7")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World8")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World9")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World10")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World11")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World12")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World13")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World14")){
            doSomething = "Hello World0";

        } else if(input.equals("Hello World15")){
            doSomething = "Hello World0";

        }
    }
    System.out.println("Time taken for String in if/else if :"+ (System.currentTimeMillis() - start));









    //METHOD_3 : MAP
    //Create and build Map
    Map<String, ExecutableClass> map = new HashMap<String, ExecutableClass>();
    for (int i = 0; i <= 15; i++) {
        String input = "Hello World" + (i & 0xF);
        map.put(input, new ExecutableClass(){
                            public void execute(String doSomething){
                                doSomething = "Hello World0";
                            }
                        });
    }


    //Start test map
    start = System.currentTimeMillis();
    for (int i = 0; i < 99999999; i++) {
        String input = "Hello World" + (i & 0xF);
        map.get(input).execute(doSomething);
    }
    System.out.println("Time taken for String in Map :"+ (System.currentTimeMillis() - start));






    //METHOD_4 : ENUM (This doesn't use muliple string with space.)
    start = System.currentTimeMillis();
    for (int i = 0; i < 99999999; i++) {
        String input = "HW" + (i & 0xF);
        HelloWorld.valueOf(input).execute(doSomething);
    }
    System.out.println("Time taken for String in ENUM :"+ (System.currentTimeMillis() - start));


    }

}

interface ExecutableClass
{
    public void execute(String doSomething);
}



// Enum version
enum HelloWorld {
    HW0("Hello World0"), HW1("Hello World1"), HW2("Hello World2"), HW3(
            "Hello World3"), HW4("Hello World4"), HW5("Hello World5"), HW6(
            "Hello World6"), HW7("Hello World7"), HW8("Hello World8"), HW9(
            "Hello World9"), HW10("Hello World10"), HW11("Hello World11"), HW12(
            "Hello World12"), HW13("Hello World13"), HW14("Hello World4"), HW15(
            "Hello World15");

    private String name = null;

    private HelloWorld(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void execute(String doSomething){
        doSomething = "Hello World0";
    }

    public static HelloWorld fromString(String input) {
        for (HelloWorld hw : HelloWorld.values()) {
            if (input.equals(hw.getName())) {
                return hw;
            }
        }
        return null;
    }

}





//Enum version for betterment on coding format compare to interface ExecutableClass
enum HelloWorld1 {
    HW0("Hello World0") {   
        public void execute(String doSomething){
            doSomething = "Hello World0";
        }
    }, 
    HW1("Hello World1"){    
        public void execute(String doSomething){
            doSomething = "Hello World0";
        }
    };
    private String name = null;

    private HelloWorld1(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void execute(String doSomething){
    //  super call, nothing here
    }
}


/*
 * http://stackoverflow.com/questions/338206/why-cant-i-switch-on-a-string
 * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10
 * http://forums.xkcd.com/viewtopic.php?f=11&t=33524
 */ 

Time taken for String in Switch :3235 Time taken for String in if/else if :3143 Time taken for String in Map :4194 Time taken for String in ENUM :2866
halil

@halil ฉันไม่แน่ใจว่าโค้ดนี้ทำงานอย่างไรในสภาพแวดล้อมที่แตกต่างกัน แต่คุณได้พูดถึงว่า / elseif ดีกว่าสวิตช์และแผนที่หรือไม่ฉันไม่สามารถโน้มน้าวใจได้เนื่องจาก if / elseif ต้องทำการเปรียบเทียบไม่มากเท่า
Kanagavelu Sugumar

2

สำหรับบล็อกswitchส่วนใหญ่และส่วนใหญ่if-then-elseฉันนึกไม่ออกว่ามีข้อกังวลเกี่ยวกับประสิทธิภาพที่น่าชื่นชมหรือมีนัยสำคัญ

แต่นี่คือสิ่งที่: หากคุณใช้switchบล็อกการใช้งานอย่างมากแสดงให้เห็นว่าคุณกำลังเปลี่ยนค่าที่นำมาจากชุดค่าคงที่ที่ทราบในเวลาคอมไพล์ ในกรณีนี้คุณไม่ควรใช้switchคำสั่งเลยหากคุณสามารถใช้enumวิธีการเฉพาะค่าคงที่

เมื่อเทียบกับswitchคำชี้แจง enum ให้ความปลอดภัยและรหัสที่ดีกว่าซึ่งง่ายต่อการบำรุงรักษา สามารถออกแบบ Enums เพื่อที่ว่าถ้าค่าคงที่ถูกเพิ่มเข้าไปในชุดของค่าคงที่โค้ดของคุณจะไม่คอมไพล์โดยไม่ต้องระบุวิธีการเฉพาะค่าคงที่สำหรับค่าใหม่ ในทางกลับกันการลืมเพิ่มบล็อกใหม่caseในswitchบางครั้งอาจถูกจับได้เฉพาะเวลาดำเนินการเท่านั้นหากคุณโชคดีพอที่จะตั้งค่าบล็อกของคุณเพื่อให้เกิดข้อยกเว้น

ประสิทธิภาพระหว่างswitchและenumวิธีการเฉพาะค่าคงที่ไม่ควรแตกต่างกันอย่างมีนัยสำคัญ แต่วิธีหลังอ่านง่ายกว่าปลอดภัยกว่าและดูแลรักษาง่ายกว่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.