在javascript中嵌套'切换'案例:任何速度优势?

时间:2011-10-18 13:28:23

标签: javascript performance switch-statement

新手问题:我有一个包含大量字符串的“开关”。按字母顺序分割是否有速度优势,就像这样?

switch(myString.substring(0,1)){
case "a" : switch(myString){
           case "a string beginning with a"       : runCode(); break;
           case "another string beginning with a" : runCode(); break;
           } break;
case "b" : switch(myString){
           case "by golly another string"         : runCode(); break;
           case "blimey - hundreds of strings"    : runCode(); break;
           //... etc

或者,无论如何,脚本语言都会读取每一行,只是为了找到封闭的括号?

4 个答案:

答案 0 :(得分:6)

是和否。您会看到最低速度增益,但不值得从这种结构中丢失代码可读性。 switch语句就像if-else语句的巨大块。它必须从一个案例转到另一个案例,直到它找到它正在寻找的东西,就像if-elseif-else结构相当于它。因此,你所做的只是帮助它跳过一些条件。嵌套的switch语句,特别是这里编写的方式,对于大多数开发人员而言,其可读性低于直接if-elseif-else层次结构。

答案 1 :(得分:4)

我认为你不应该介意这样的优化。我会说最好用要执行的函数创建一个对象,这样你就不需要过多的查找代码了,但是就像这样:

var obj = {
    "aa": runCode,
    "ab": something,
    "ba": foo,
    "bb": bar
};

然后你只能执行此操作,而不是switch内的switch es。它将在内部查找正确的函数,我认为这比自己做这些事情要快:

obj[myString]();

答案 2 :(得分:1)

我没有在JS版本上运行基准测试,但我知道在PHP中使用switch与if / else有一点点不利,但差异可以忽略不计,在某些情况下你会获得可读性/可维护性在速度(imho)。

那就是说,我不相信你在这里获得任何速度,除非你更有可能获得a,b,c结果而不是x,y,z结果。在评估case语句时,解析器将评估每个案例,直到找到匹配项,然后进入该代码。

因此,如果您的答案比其他答案更频繁,并将这些答案放在顶部,那么从技术上讲可以节省评估时间,但我认为节省的时间可以忽略不计。也就是说,基于它的基准循环几千次可能会显示出微秒的差异。我实在太懒了,但是这是我最好的猜测。

并且巢开关语句通常被避开,因为它们不是很漂亮并且难以阅读,这可能引入错误和/或沮丧的同事。 :)

答案 3 :(得分:1)

我想正确的答案可能是凭经验测量的 - 并且可能因JavaScript执行引擎而异。

基本上我们需要看一下根据伪代码编译脚本的最佳情况。

最糟糕的情况是一个天真的连续字符串比较集 - 即它依次评估每个案例标签进行字符串比较 - 在​​过去几年的所有速度声明中,我怀疑任何主要引擎都会做除非案件标签的数量很少(比如2或3)。

对于大量案例标签,最佳执行速度是引擎首先创建所有案例标签的哈希表(在脚本加载时完成一次),然后执行switch语句,计算输入的哈希值,并查找最终字符串比较的一组可能的目标值。

如果执行引擎执行此操作,则切换语句的嵌套实际上会使所花费的时间加倍 - 从而降低执行速度。

所以一般来说,对于现代javascript引擎(浏览器中使用的那些引擎),信任系统做正确的事情而不会产生不可读的代码 - 对于旧的和模糊的javascript引擎(使用服务器端的那些不是Node.JS)测试你做了什么。