Switch语句中的大小写顺序是否会改变性能?

假设我有一个如下的switch语句

switch(alphabet) { case "f": //do something break; case "c": //do something break; case "a": //do something break; case "e": //do something break; } 

现在假设我知道有Alphabet e的频率最高,分别是a,c和f。 所以,我只是重新组织了case语句顺序,并按如下方式进行了重构:

 switch(alphabet) { case "e": //do something break; case "a": //do something break; case "c": //do something break; case "f": //do something break; } 

第二个switch语句会比第一个switch语句快吗? 如果是,如果在我的程序中我需要多次调用此switch语句,那将是一个实质性的改进吗? 或者,如果没有,我如何使用我的频率知识来提高性能?

并不是说你应该担心。 这当然不是可以预测的东西。

对于字符串大小写标签,编译器实际上使用内部哈希表将字符串映射到跳转表中的索引。 因此操作实际上是O(1) – 与标签数量无关。

对于整数标签,我相信生成的实际代码取决于标签的数量以及数字是否连续(或“几乎”连续)。 如果它们是连续的(1,2,3,4 ……),那么它们将被转换成跳转表。 如果有很多,那么将使用Hashtable +跳转表(如字符串)。 如果只有少数标签并且它们不是立即转换为跳转表的表, 那么只有那时才会转换成一系列if..then..else语句。

但是,一般情况下,您应该编写代码以便可以读取代码,而不是编译器可以生成“更快”的代码。

(注意我上面的描述是C#编译器如何在内部工作的实现细节:你不应该依赖它总是这样工作 – 实际上,它甚至可能不会像现在这样工作,但至少它是一般的想法)。

这取决于编译器如何实现switch语句。

首先,你不能随意置换顺序; 如果你有一个类似C语言的案例块(C,C ++,C#,Java,…),并且该案例块不会在中断时终止,则无法重新排列案例,因为没有中断意味着编译器必须实现下一个案例的落实。 如果我们忽略这种特殊情况,您可以置换其余的情况。

如果案例数量很少,编译器可以通过一系列比较来实现案例测试。 如果案例数量适中,则可以根据案例构建平衡二叉树。 如果案例数量很大,则大多数编译器在交换机值上实现索引分支(如果它来自密集集)。 如果一组案例值的一部分是密集的,而部分不是,则编译器可以使用二叉树将案例分成组,以选择哪个密集集,以及密集集内的索引跳转。 (事实上​​,编译器在技术上可以做任何将控制传递给适当的情况的东西,但大多数情况下它是上面的一种)。

您可以看到顺序可能很重要,也可能不重要,具体取决于编译器如何实现切换。 对于大多数优秀的编译器来说,它并不重要。

它们对于相对较小的值集具有相同的性能。 我之前尝试检查C程序的汇编代码,编译器从switch语句中的所有值中创建一个跳转表。

但是,如果案例值过多,那么可以肯定的是, if将它们de de else if ,so so so so would would would would would would would would would would would would would would would would would would would would would

它也适用于C#,C#还为带有小集合的switch语句生成跳转表,尽管只是相邻的值。 所以它是O(1),即使第一个值不匹配也没有多重测试。

我认为切换案例的方式是从上到下遍历所有情况以找到一些匹配。 如果它匹配,它就会停在那里。

因此,如果您进行了更改以确定频率案例的优先级,答案是肯定的,它可以在某种程度上提高性能。 但我相信这无济于事。