切换语句更大

所以我想用这样的switch语句:

switch (scrollLeft) {
  case (<1000):
   //do stuff
   break;
  case (>1000 && <2000):
   //do stuff
   break;
}

现在我知道这些语句( <1000 )或( >1000 && <2000 )中的任何一个都不起作用(显然由于不同的原因)。 我所要求的是最有效的方式。 我讨厌使用30条if语句,所以我宁愿使用switch语法。 有什么我可以做的吗?


当我在其他答案中查看解决方案时,我看到了一些我知道对性能不利的事情。 我打算将它们置于评论中,但我认为最好是对它进行基准测试并分享结果。 你可以自己测试一下。 下面是我的结果(ymmv)在每个浏览器中最快操作之后归一化(将1.0倍时间与标准化值相乘以获得绝对时间,单位为毫秒)。

                    Chrome  Firefox Opera   MSIE    Safari  Node
-------------------------------------------------------------------
1.0 time               37ms    73ms    68ms   184ms    73ms    21ms
if-immediate            1.0     1.0     1.0     2.6     1.0     1.0
if-indirect             1.2     1.8     3.3     3.8     2.6     1.0
switch-immediate        2.0     1.1     2.0     1.0     2.8     1.3
switch-range           38.1    10.6     2.6     7.3    20.9    10.4
switch-range2          31.9     8.3     2.0     4.5     9.5     6.9
switch-indirect-array  35.2     9.6     4.2     5.5    10.7     8.6
array-linear-switch     3.6     4.1     4.5    10.0     4.7     2.7
array-binary-switch     7.8     6.7     9.5    16.0    15.0     4.9

测试以下版本在Windows 7 32bit上执行的操作:Chrome 21.0.1180.89m,Firefox 15.0,Opera 12.02,MSIE 9.0.8112,Safari 5.1.7。 节点在Linux 64位盒子上运行,因为Node.js for Windows上的计时器分辨率是10ms而不是1ms。

如果,即时

这是所有测试环境中速度最快的,除了... drumroll MSIE! (惊喜,惊喜)。 这是实施它的推荐方式。

if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else

如果间接

这是switch-indirect-array一个变体,但是在几乎所有测试的环境中都使用if -statements,而且执行速度比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倍的时间。 但在1337ms(!),实际的时间差只有74ms赞成MSIE。

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语句的顺序很重要,因为引擎会以源代码的顺序测试每个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 -statements或使用即时值进行switch


替代:

var scrollleft = 1000;
switch (true)
{
    case (scrollleft > 1000):
      alert('gt');
      break;
    case (scrollleft <= 1000):
      alert('lt');
      break; 
}

演示:http://jsfiddle.net/UWYzr/


switch (scrollLeft/1000) {
  case 0: // (<1000)
   //do stuff
   break;
  case 1: // (>=1000 && <2000)
   //do stuff;
   break;
}

只有在你有规律的步骤时才有效......

编辑:由于这个解决方案不断得到upvotes,我必须建议,mofolo的解决方案是一个更好的方法

链接地址: http://www.djcxy.com/p/10029.html

上一篇: Switch statement for greater

下一篇: Numeric comparison difficulty in R