我有以下相当简单的 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; }
1 回答
九州编程
TA贡献1785条经验 获得超4个赞
这是一个非常聪明的优化,它可以让几乎独立于语句块中的switch
字符串数量的时间来完成它的工作。case
这种优化是基于观察到相同字符串的哈希码必须相同。编译器不是逐个检查字符串是否相等,而是计算一次目标字符串的哈希,并在 O(1) 中执行基于表的查找。这使编译器达到所需的情况,此时编译器需要检查字符串是否实际相等。
请注意,当多个查找字符串具有相同的哈希码时,会出现一些罕见的情况。在这种情况下,生成的case
语句将包含多个if
以在具有相同哈希码的字符串中做出决定。
总的来说,这种行为模仿了基于散列的字典的行为:散列码确定case
(相当于散列桶),而里面的一系列if
s 确定是否存在匹配。这会带来更好的性能,因为它可以让编译器跳过不必要的检查。
- 1 回答
- 0 关注
- 149 浏览
添加回答
举报
0/150
提交
取消