当我查看其他答案中的解决方案时,我看到了一些我所知道的不利于性能的内容。我本打算在评论中发表评论,但我认为最好对其进行基准测试并分享结果。您可以自己进行测试。下面是我在每个浏览器中以最快的速度进行操作后归一化的结果(ymmv)(将1.0的时间乘以归一化的值即可得出以毫秒为单位的绝对时间)。
Chrome Firefox Opera MSIE Safari节点
-------------------------------------------------- -----------------
1.0时间37ms 73ms 68ms 184ms 73ms 21ms
如果立即1.0 1.0 1.0 2.6 1.0 1.0
如果间接1.2 1.8 3.3 3.8 2.6 1.0
即时交换2.0 1.1 2.0 1.0 2.8 1.3
开关范围38.1 10.6 2.6 7.3 20.9 10.4
开关范围2 31.9 8.3 2.0 4.5 9.5 6.9
开关间接阵列35.2 9.6 4.2 5.5 10.7 8.6
阵列线性开关3.6 4.1 4.5 10.0 4.7 2.7
数组二进制开关7.8 6.7 9.5 16.0 15.0 4.9
测试在以下版本的Windows 7 32位上执行的位置:Chrome 21.0.1180.89m,Firefox 15.0,Opera 12.02,MSIE 9.0.8112,Safari 5.1.7。Node在Linux 64位机上运行,因为Windows的Node.js上的计时器分辨率是10ms,而不是1ms。
如果立即
这是在所有经过测试的环境中最快的速度,除了... 感光鼓 MSIE!(惊喜)。这是推荐的实现方法。
if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
如果间接
这是-statement 的变体,switch-indirect-array
但是具有if
-statement,并且比switch-indirect-array
几乎所有测试环境中的执行速度都要快。
values=[
1000, 2000, ... 30000
];
if (val < values[0]) { /* do something */ } else
if (val < values[1]) { /* do something */ } else
...
if (val < values[29]) { /* do something */ } else
立即切换
在所有经过测试的环境中,这都是非常快的,实际上是MSIE中最快的。当您可以进行计算以获取索引时,它将起作用。
switch (Math.floor(val/1000)) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
开关范围
这比所有经过测试的环境中最快的速度慢6至40倍,Opera所需的时间大约是其一半左右。这很慢,因为引擎必须针对每种情况两次比较该值。令人惊讶的是,与Chrome中最快的操作相比,Chrome需要近40倍的时间来完成此操作,而MSIE只需6倍的时间。但是实际的时差仅为74ms,而MSIE为1337ms(!)。
switch (true) {
case (0 <= val && val < 1000): /* do something */ break;
case (1000 <= val && val < 2000): /* do something */ break;
...
case (29000 <= val && val < 30000): /* do something */ break;
}
开关范围2
这是一个变体,switch-range
但每个案例只有一个比较,因此比较快,但在Opera中除外,但仍然非常慢。case语句的顺序很重要,因为引擎将按照源代码顺序ECMAScript262:5 12.11测试每个案例。
switch (true) {
case (val < 1000): /* do something */ break;
case (val < 2000): /* do something */ break;
...
case (val < 30000): /* do something */ break;
}
开关间接阵列
在此变体中,范围存储在数组中。在所有经过测试的环境中,速度都很慢;在Chrome中,速度非常慢。
values=[1000, 2000 ... 29000, 30000];
switch(true) {
case (val < values[0]): /* do something */ break;
case (val < values[1]): /* do something */ break;
...
case (val < values[29]): /* do something */ break;
}
阵列线性搜索
这是对数组中的值进行线性搜索以及使用固定值的switch语句的组合。可能要使用它的原因是,直到运行时才知道这些值。在每个经过测试的环境中,它的速度都很慢,而在MSIE中的时间几乎是它的10倍。
values=[1000, 2000 ... 29000, 30000];
for (sidx=0, slen=values.length; sidx < slen; ++sidx) {
if (val < values[sidx]) break;
}
switch (sidx) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
阵列二进制开关
这是的变体,array-linear-switch
但带有二进制搜索。不幸的是,它比线性搜索要慢。我不知道这是我的实现还是线性搜索是否更优化。键空间也可能很小。
values=[0, 1000, 2000 ... 29000, 30000];
while(range) {
range = Math.floor( (smax - smin) / 2 );
sidx = smin + range;
if ( val < values[sidx] ) { smax = sidx; } else { smin = sidx; }
}
switch (sidx) {
case 0: /* do something */ break;
...
case 29: /* do something */ break;
}
结论
如果性能很重要,请使用if
-statement或switch
立即值。