嗚嗚喔學習筆記

搜尋此網誌

2022年7月6日 星期三

C# Switch case vs if else 效能分析

先說結論 : Switch case 再Case數量 > 5 之後比 if else 還快 ( 但快非常少 )

為什麼? 他經過什麼轉換?

Switch Case 是語法糖 所以他會經過轉換 基本上就是轉成 if else 的形式 只是會做一些優化處理

以下為轉換程式碼

如果 case 是數字常數時->會轉成樹狀查詢

int a = 100;
switch(a)
{
    case 100 :
        Do();
        break;
    case 200 :
        Do();
        break;
    case 300 :
        Do();
        break;
    case 400 :
        Do();
        break;
    case 500 :
        Do();
        break;
    case 600 :
        Do();
        break;
    default :
        break;
}

轉成:

int num = 100;
int num2 = num;
int num3 = num2;
if (num3 <= 300)
{
    if (num3 != 100)
    {
        if (num3 != 200)
        {
            if (num3 == 300)
            {
                Do();
            }
        }
        else
        {
            Do();
        }
    }
    else
    {
        Do();
    }
}
else if (num3 <= 500)
{
    if (num3 != 400)
    {
        if (num3 == 500)
        {
            Do();
        }
    }
    else
    {
        Do();
    }
}
else if (num3 != 600)
{
    if (num3 == 700)
    {
        Do();
    }
}
else
{
    Do();
}

物件格式:

Object b = "100";
switch(b)
{
    case "100" :
        Do();
        break;
    case "200" :
        Do();
        break;
    case "300" :
        Do();
        break;
    case "400" :
        Do();
        break;
    case "500" :
        Do();
        break;
    case "600" :
        Do();
        break;
    case "700" :
        Do();
        break;
    default :
        break;
}

case 數量 >5 時 會先轉HashCode 所以能夠被樹狀查詢 ( 會比較快點 ) 轉成:

object obj = "100";
object obj2 = obj;
object obj3 = obj2;
string text = obj3 as string;
if (text == null)
{
    return;
}
uint num = <PrivateImplementationDetails>.ComputeStringHash(text);
if (num <= 1162866994)
{
    if (num != 147274918)
    {
        if (num != 731423408)
        {
            if (num == 1162866994 && text == "300")
            {
                Do();
            }
        }
        else if (text == "500")
        {
            Do();
        }
    }
    else if (text == "700")
    {
        Do();
    }
}
else if (num <= 2291914577u)
{
    if (num != 1731450012)
    {
        if (num == 2291914577u && text == "600")
        {
            Do();
        }
    }
    else if (text == "100")
    {
        Do();
    }
}
else if (num != 2855274715u)
{
    if (num == 3286718301u && text == "200")
    {
        Do();
    }
}
else if (text == "400")
{
    Do();
}

結論: 當switch case 是數字常數時會比較快 or 非數字常數要超過5個以上才會優化

參考:

https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQAwAIpwHQGED2ANoQKYDGALgJb4B2AzgNzJqZwAszKGW2AMlVoBHLlADMmGOlzoA3snSL0CpeMzt0ASQBmAUUL0SuAIaGAFAEoVi+UiX30giumPoAvOjipUXB0qraZq5uHl6oFnLoACL4lowAvtYOJAYkjoHBHjDeEbLRsRYJSfYphulB7h5iOZExcYl2fuilaQEVIejsNXl1hQ1NzanlmegArN359cVKLcOV6ABsE71FjYr9SklqUBqatBQAygDuVBRkABYmhqhwlkm2A04u7p7evk30J2fnQVZrDg8BkoyKY0mF0CBpkDJoUoUCAEYAJxIxgA1u9oSCytkMJD/tDFCs4QMkSj0cTgaD0NVcRS/ET8QTSWiMUCsWkurTGdCGQSHMzydyHOyxt4IXSHLy+UoBayBiKlqg8dKlFKVbKJSKAOzeZUqmFypnIlkS4AkbTGACuhGcevVxsFAw26y2Eh2Wn2x1OFyuJFQMDu/0BfiewVePjhn29P2MfwGwbZVPBdulaulGqF9hFOPFmaaab5Gb5Ippuf1Bol9iLBJFnLL+oLRrJhr8IvGXPLjeh1cxVMV9ZVXYRDpbDjNFuttsrMpHcOd6HnrvU6AA8vCAFbkQ5fH2gm6B+wJ+xrzeUdDwl4AIjCl9HUe+ZnhcaaR6aIuv3kvA9TBVHJNneaKO+OJfimfJDv+zaalSl40qB06Er+CHngBxYwZy8GAZKSFYVWqE1jB7aYZ2OHlj2iZlJeirEQ2pH6uR8owTqqA0YOdH2lBWHjlaNrfoW+F+POi7/NsGgnluXrfL6/oHkor6KOJZ4Xh4H4sXeO4/E+cLycKME3nxBIQU0DFvjBIEGTy7HpgJFFpLBn4WUCRl+CZrboQ5YGGVZ/GcWhlFEY5AzOfyNmMZR1GBfm3lNiaXHmjxU64TOvlNEJSRJAADoiVAAG7GBQaTur0sgNPEQA===