Javascript切换与if ... else if ... else


143

伙计们,我有几个问题:

  1. switch语句和an 之间在JavaScript中是否存在性能差异if...else
  2. 如果可以,为什么?
  3. 是的行为switchif...else跨浏览器的不同?(FireFox,IE,Chrome,Opera,Safari)

提出这个问题的原因是,switch在Firefox中大约有1000多个案例的情况下,我似乎获得了更好的性能。


编辑 Unfortuantly这不是我的代码JavaScript是正在生产服务器端从编译的库,我要的代码的访问权限。产生javascript的方法称为

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

note arrayofvalues是用逗号分隔的列表。

它产生的是

function [name] (value) {
  if (value == [value from array index x]) {
     [action from array index x]
  }
}

注意:其中[name]=传递给服务器端函数的名称

现在,我更改了要插入TextArea的函数的输出,编写了一些JavaScript代码以解析该函数​​,然后将其转换为一组case语句。

最后,我运行了该函数,并且运行良好,但是在IE和Firefox中性能有所不同。


1
我建议使用一个代码示例来检查什么是最佳的。我的意思是,您要问这个一定有原因吧?
jcolebrand

请发表您的意见,因为在我的长期经验中,很少有案例是100例​​switch语句或100部分if / else系列是一个好主意。
尖尖的

抱歉,不是100
岁,

2
大家,谢谢您的投入。但是我的问题实际上不是if和swith陈述之间的区别。这是在语句内部运行的代码。向所有人+1寻求帮助。很抱歉给您带来不便。有时,您只需要与其他人讨论一下即可找到解决方案。
约翰·哈索克

Answers:


113

一般回答:

  1. 是的,通常。
  2. 在这里查看更多信息
  3. 是的,因为每个人都有不同的JS处理引擎,但是,在下面的站点上运行测试时,开关总是在大量迭代中执行if,elseif。

测试地点


1
如果你想的时使用的条件语句一个TLDR这里是一个直接链接到段文章中寻址:oreilly.com/server-administration/excerpts/even-faster-websites/...
edhedges

2
@Tommy好文章,谢谢分享。但是,文章指出JS中switchif/then语句之间的性能差异可以忽略不计。文章指出,这是由于斑点switch优化和不同JS引擎运行方式不同所致。Quote:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
贾斯珀

3
此说明中是否可以量化?它看起来像许多“最佳实践/过早优化”的猜想。它也是7年前编写的,因此javascript优化在这段时间已发生了巨大变化。在编译语言中,这三个操作之间的性能差异“几乎从来没有足够重要”。不要费心去优化那些不会影响实际性能的东西。优化可读性。
Thomson Comer'2

3
@Tommy« 在这里查看更多信息 »给出404,那是什么?
LogicDaemon

2
@LogicDaemon-IIRC是指向一些oRielly文本框的链接,该文本框涉及了一些深入的JS性能注意事项/讨论
Tommy,

61

有时最好不使用它们。例如,在“派遣”情况下,Javascript让您以完全不同的方式进行操作:

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

通过创建对象来设置多路分支有很多优点。您可以动态添加和删除功能。您可以从数据创建调度表。您可以通过编程方式进行检查。您可以使用其他功能构建处理程序。

函数调用要达到等于“ case”的条件,因此会增加额外的开销,但是使用散列查找的优势(如果有很多case),可以找到特定键的函数。


2
您的策略很好,我经常使用。但是,正如@Michael Geary stackoverflow.com/a/45336805/5936119指出的那样,必须在调度上下文之外声明map变量,否则它将始终被重新评估。
丹尼尔·桑塔纳

@DanielSantana正确,但我怀疑这是否昂贵。特别是,一旦对函数进行了最初的解析,由于文本是静态的,因此无需重新生成代码本身。
尖尖的

18

switch和之间的性能差异if...else if...else很小,它们基本上可以完成相同的工作。它们之间可能有所不同的一个不同之处在于,要测试的表达式仅在switch为每个表达式求值的同时进行一次求值if。如果评估表达式的成本很高,则执行一次当然比执行一百次要快。

在浏览器之间,这些命令(以及通常的所有脚本)在实现上的差异很大。通常会在不同的浏览器中看到相同代码的巨大性能差异。

由于几乎无法在所有浏览器中对所有代码进行性能测试,因此应选择最适合您所执行工作的代码,并尝试减少已完成的工作量,而不是优化工作方式。


7
  1. 如果存在差异,它将永远不会太大而无法引起注意。
  2. 不适用
  3. 不,它们的功能都相同。

基本上,使用使代码更具可读性的方法。肯定在某些地方可以使一种或多种结构更清洁,更具可读性和更易于维护。这可能比在JavaScript代码中节省几纳秒要重要得多。


5
特别是在javascript中,语义和可读性(以及因此的可维护性)胜过独特的浏览器版本计算机硬件和OS组合之间的if..elseswitch由其引起的任何本地化性能差异。
jball

2
我不知道我是否同意,如果在说,一个大型数据库循环中使用它可能确实注意到,遍历树等
ghoppe

2
我绝对不同意。随着Web应用程序变得越来越复杂,这种差异对于应用程序而言可能非常重要,并且可能会因浏览器而异。
joshvermaire

7
重要的是编写干净,可维护的代码。看到性能问题时-配置文件。然后确定要修复的代码。不要为假定的性能问题而牺牲可维护性。
乔恩·本尼迪克托

3
'if else if else ...'是O(n),而'switch'是O(1)或O(log(n))。老实说,你怎么能说差异永远不会太大?切换一百万个案例(如果生成代码,这很容易实现),您肯定会注意到它至少可以说。
龙卷根

6

除了语法以外,还可以使用使其成为树的开关来实现开关O(log n),而if / else必须通过O(n)过程方法来实现。它们通常都在程序上进行处理,唯一的区别是语法,而且这真的很重要-除非您仍然静态地输入1万个if / else大小写?


7年后...除了恒定数值大小写值的情况外,我看不到如何实现树。
Ed Staub'2

4

Pointy的答案建议使用对象文字代替switchif/ else。我也喜欢这种方法,但是map每次dispatch调用该函数时,答案中的代码都会创建一个新对象:

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

如果map包含大量条目,则可能会产生大量开销。最好只设置一次操作映射,然后每次使用已经创建的映射,例如:

var actions = {
    'explode': function() {
        prepExplosive();
        if( flammable() ) issueWarning();
        doExplode();
    },

    'hibernate': function() {
        if( status() == 'sleeping' ) return;
        // ... I can't keep making this stuff up
    },
    // ...
};

function dispatch( name ) {
    var action = actions[name];
    if( action ) action();
}

3

在switch语句和if ... else if .... else之间,JavaScript在性能方面是否存在差异?

我不这么认为,switch如果您想避免多种if-else情况,则是有用/简短的。

各个浏览器的switch和if ... else if ... else行为是否不同?(FireFox,IE,Chrome,Opera,Safari)

所有浏览器的行为均相同:)


5
switch is useful/short if you want prevent multiple if-else conditions.是的,先生,很棒的帖子
NiCk Newman 2015年

1
  1. 在某些情况下,工作台可能会导致一些很小的差异,但是处理方式始终取决于浏览器,因此不值得打扰
  2. 由于处理方式不同
  3. 如果行为会有所不同,则不能将其称为浏览器

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.