2010-05-27 86 views
95

家伙,我有几个问题:的Javascript开关主场迎战如果...否则,如果...否则

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

问这个问题的原因似乎是,我在Firefox的约1000个案例中的switch声明中获得了更好的性能。


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

CreateConditionals(string name, string arrayofvalues, string arrayofActions) 

arrayofvalues是一个逗号分隔的列表。

它所产生的是

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

注:其中[name] =传递到服务器端功能

现在我改变了函数的输出要插入一个文本区的名字,写了一些JavaScript代码通过函数解析,并将其转换为一组case语句。

最后我执行此功能,它运行良好,但性能在IE和Firefox不同。

+1

我会建议一个代码示例来检查哪些是最佳的。我的意思是,你有这个问题的理由,对吧? – jcolebrand 2010-05-27 16:34:57

+0

请发表您的评论,因为在我长期的经历中,我很少会遇到这样的情况,我会说100个开关语句或100个部分的if/else系列是个好主意。 – Pointy 2010-05-27 16:40:54

+0

对不起,你们不是100几岁,而是成千上万的条件 – 2010-05-27 17:04:42

回答

74

接听泛泛:

  1. 是的,平常LY。
  2. See More Info Here
  3. 是的,因为每个人都有不同的JS处理引擎,但是,在下面的网站上运行测试时,交换机总是在大量迭代中执行if,elseif。

Test site

+0

感谢tommy您的示例网站在尝试确定if和switch之间的性能差异时很好用。它非常小,它使我得出结论,我的问题在其他地方,正如我在对我的问题发表评论时指出的那样。谢谢你的时间。 – 2010-05-27 17:36:53

+1

+1非常有趣的文章 – Martin 2012-08-09 18:57:33

+1

如果你想的时候这里使用的条件语句一个TLDR是直接链接到段的文章在解决:http://oreilly.com/server-administration/excerpts/even-faster -websites /写高效,javascript.html#the_fastest_conditionals – edhedges 2013-05-06 13:43:37

3

是否有一个switch语句 并且如果之间 JavaScript中的性能与区别...如果还有别的....?

我不这么认为,switch是有用/短,如果你想防止多个if-else条件。

是开关的行为,并 如果...否则,如果...跨浏览器 什么不同呢? (火狐,IE浏览器,铬,歌剧,Safari浏览器 )

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

+2

'如果你想防止多个if-else条件,'switch是有用/短的.'是的,先生,伟大的职位。 – 2015-07-14 02:55:27

6
  1. 如果是有区别的,它永远不会大到足以被注意到。
  2. N/A
  3. 不,它们的功能完全相同。

基本上,使用任何使代码最具可读性的代码。确实有一个或其他结构可以使清洁,更易读和更易维护。这更重要,可能会在JavaScript代码中节省几纳秒。

+4

特别是在javascript中,语义和可读性(以及可维护性)胜过由唯一浏览器版本计算机硬件和操作系统组合导致的'if..else'和'switch'之间的任何本地化性能差异。 – jball 2010-05-27 16:40:21

+1

我不知道我是否同意,它可能确实被注意到,如果它被用于循环与说,一个大型数据库,遍历树等 – ghoppe 2010-05-27 16:50:47

+1

我绝对不同意。随着Web应用程序变得越来越复杂,这种差异可能对应用程序有重大意义,并可能依赖于浏览器而改变。 – joshvermaire 2011-11-22 23:52:17

1
  1. Workbenching可能导致在某些情况下,一些非常小的差异,但处理的方式是依赖于浏览器反正太不值得费心
  2. 由于处理
  3. 不同的方式,你不能把它的浏览器,如果该行为会有所不同,无论如何
6

除了语法,一个开关可以用一棵树,这使得它O(log n)来实现,而的if/else必须与O(n)程序的方法来实现。更经常地,它们都是程序处理的,唯一的区别就是语法,而且它真的很重要 - 除非静态地输入10k个if/else的case吗?

+0

7年后......我没有看到树实现是如何实现的,除了在数值常量值不变的情况下)。 – 2017-02-11 15:03:02

49

有时候最好不要使用。例如,在“调度”的情况下,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”的等价物的额外开销,但是有一个散列查找的优点(当有大量情况时)为特定的键查找函数。

13

switchif...else if...else之间的性能差异很小,它们基本上做了同样的工作。他们之间可能有差异的一个区别是,要测试的表达式仅在switch中评估一次,而对每个if进行评估。如果评估这个表达的代价是昂贵的,那么这样做一次当然要比做一百次更快。

这些命令(以及所有脚本一般)的实现差异在浏览器之间有很大不同。在不同的浏览器中看到相同的代码有相当大的性能差异是很常见的。

正如你很难性能测试在所有浏览器所有的代码,你应该去那个最适合你在做什么的代码,并尽量减少工作的完成,而不是优化它是如何做的量。

0

Pointy's answer建议使用对象常量来替代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(); 
}