为什么编译器会在 switch 中添加语句?

我有以下相当简单的 switch 语句。// 较早的字符串 fullPath = GetFullPath(); 字符串类型 = GetEntityType();


switch (type.ToLower()) {

    case "tables":

        tables.Add(fullPath);

        break;

    case "views":

        views.Add(fullPath);

        break;

    case "functions":

        functions.Add(fullPath);

        break;

    case "storedprocs":

        storedprocs.Add(fullPath);

        break;

    case "data":

        data.Add(fullPath);

        break;

    case "layouts":

        layouts.Add(fullPath);

        break;

    case "scripts":

        scripts.Add(fullPath);

        break;

    default:

        Console.WriteLine($"What is this: {type}");

        break;

}

当我使用 Reflector 反编译生成的二进制文件时,switch(string)它已更改为 ComputeStringHash,然后在每个 case 语句中,它通过if语句检查值。听起来它正在做双倍的工作。


    string s = str2.ToLower();

    switch (<PrivateImplementationDetails>.ComputeStringHash(s))

    {

        case 0x20890fc4:

            if (s == "tables")

            {

                break;

            }

            goto Label_0218;


        case 0x454a414e:

            if (s == "functions")

            {

                goto Label_01DE;

            }

            goto Label_0218;


        case 0x4facf6d1:

            if (s == "views")

            {

                goto Label_01D3;

            }

            goto Label_0218;


        case 0xcdfe2cb3:

            if (s == "storedprocs")

            {

                goto Label_01E9;

            }

            goto Label_0218;


        case 0xd872e2a5:

            if (s == "data")

            {

                goto Label_01F4;

            }

            goto Label_0218;


        case 0x9b4a129b:

            if (s == "scripts")

            {

                goto Label_020C;

            }

            goto Label_0218;


        case 0xba971064:

            if (s == "layouts")

            {

                goto Label_0200;

            }

            goto Label_0218;


        default:

            goto Label_0218;

    }

BIG阳
浏览 150回答 1
1回答

九州编程

这是一个非常聪明的优化,它可以让几乎独立于语句块中的switch字符串数量的时间来完成它的工作。case这种优化是基于观察到相同字符串的哈希码必须相同。编译器不是逐个检查字符串是否相等,而是计算一次目标字符串的哈希,并在 O(1) 中执行基于表的查找。这使编译器达到所需的情况,此时编译器需要检查字符串是否实际相等。请注意,当多个查找字符串具有相同的哈希码时,会出现一些罕见的情况。在这种情况下,生成的case语句将包含多个if以在具有相同哈希码的字符串中做出决定。总的来说,这种行为模仿了基于散列的字典的行为:散列码确定case(相当于散列桶),而里面的一系列ifs 确定是否存在匹配。这会带来更好的性能,因为它可以让编译器跳过不必要的检查。
打开App,查看更多内容
随时随地看视频慕课网APP