Algorithm switch语句的运行时复杂性是多少?

Algorithm switch语句的运行时复杂性是多少?,algorithm,programming-languages,switch-statement,big-o,Algorithm,Programming Languages,Switch Statement,Big O,我想知道switch语句的最坏运行时复杂度是多少,假设您有n个实例 我一直以为是O(n)。不过,我不知道编译器是否做得很聪明。如果答案是特定于实现的,我想了解以下语言: 爪哇 信用证++ C# PHP Javascript 最坏的情况是O(n)。有时(这取决于语言和编译器),它会转换为跳转表查找(对于大小写范围不太大的“nice”开关)。那就是O(1) 如果编译器想变得时髦,我可以考虑将复杂性实现为介于两者之间的任何东西(例如,对案例执行二进制搜索,对于logn)。但是在实践中,你会得到更多的

我想知道switch语句的最坏运行时复杂度是多少,假设您有n个实例

我一直以为是O(n)。不过,我不知道编译器是否做得很聪明。如果答案是特定于实现的,我想了解以下语言:

  • 爪哇
  • 信用证++
  • C#
  • PHP
  • Javascript
    • 最坏的情况是O(n)。有时(这取决于语言和编译器),它会转换为跳转表查找(对于大小写范围不太大的“nice”开关)。那就是O(1)


      如果编译器想变得时髦,我可以考虑将复杂性实现为介于两者之间的任何东西(例如,对案例执行二进制搜索,对于logn)。但是在实践中,你会得到更多的线性时间或常数时间。

      switch语句的big-O复杂性并不是真正重要的一点。大O表示法是指当n朝无穷大增加时的性能。如果switch语句足够大,以至于渐近性能是一个问题,那么它太大了,应该重构

      除了可读性问题之外,在Java和C中,我认为您很快就会达到单个方法最大大小的一些内部限制

      对于经常调用的相对较小的switch语句,与您可以使用的其他方法相比,测量switch语句的实际性能可能会提供更多信息。可以通过在循环中重复执行操作来进行此测量


      对于更大的switch语句,我建议重构使用一个字典或类似的数据结构,它的性能大约为O(1),即使n变得非常大,也不会遇到方法大小有限的问题。

      C++编译器可以将switch语句转换为跳转表(即,构造一个跳转偏移数组,然后取该值并将其用作表中的索引)。这是O(1)

      C#编译器使用类似的方法,只是它可以组装哈希表。

      最坏的情况可能是O(n),但至少对于C/C++、Java和C#等语言来说,如果这些情况是编译时常量,则通常可以使用跳转表(并且经常使用跳转表)将复杂性提高到O(1)


      我不知道像PHP或Javascript这样更具动态性的语言是否会尝试设置跳转表。

      C和gcc编译器的O(1)表示窄范围(跳转表),或者最坏的O(logn)表示宽范围(二进制搜索).

      答案不仅是特定于语言,甚至不是特定于编译器。这取决于实际代码。某些编译器会将某些switch语句转换为跳转表。在另一个极端,这些值可能会导致调用其他函数。例如,在Ruby中,使用
      ==
      运算符检查值,该运算符可以执行任何操作g、 正则表达式的一个常用用法是正则表达式,它(在某些情况下)可能非常昂贵——因此切换的成本主要由值本身决定,而不是由值的数量决定。是否存在大于O(n)的情况(对于切换中的n种情况)?@沮丧的天哪,我希望不会。@jleedev:也许是某种邪恶的反优化编译器选项……那将是一个令人讨厌的愚人节恶作剧;)如果一个10格的switch语句被频繁调用,那么试图理解它的内部工作原理是否有意义?@Fragsworth是的,你绝对应该试着理解它是如何在内部工作的。但是Big-O告诉你的唯一一件事是它在很多情况下会有多快,比如说100+。马克的观点是,有更好的方法来分析switch语句的内部结构,而不看它的大O,比如编译器如何优化它,以及它与使用其他方法(如查找表)的比较;如果答案是O(1),那么我知道这没有帮助。因此,了解运行时的复杂性至少可以说明一些事情。@Fragsworth:它可以是O(n),但不使用文本顺序。它可能会对值进行散列,并与常量的散列进行线性比较,或者可能会对代码进行重新排序以优化其他一些事情(如寄存器分配或堆栈使用),破坏您的排序或其他许多操作things@Fragsworth:考虑O(n)的另一个问题注释是编译器可能会对条目很少的switch语句进行一些巧妙的优化,但对更多条目使用不同的(更糟糕的)策略。然后O(n)符号会告诉你更差策略的渐近性能,这根本不是你想知道的。您应该停止从大O的角度考虑问题,而是考虑实际数据的实际性能。此外,当您进行这样的微优化时,您应该对其进行分析<代码>开关(true){case expr:doSomething();}有效,即使expr不是常量。如果我没记错的话。所以跳转表不太可能出现这样的情况。有趣的+1,但你能提供一个源代码吗?@yO_u有一个网站,它为你的C代码打印反汇编代码,忘了它的名字。你可以在那里试试。