大于/小于的switch语句 [英] Switch statement for greater-than/less-than

查看:270
本文介绍了大于/小于的switch语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想使用像这样的切换语句:

so I want to use a switch statement like this:

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



现在我知道这些语句; 1000 )或(> 1000&&< 2000 )将无法正常工作。我所要求的是最有效的方式做到这一点。我讨厌使用30 if 语句,所以我宁愿使用switch语法。

Now I know that either of those statements (<1000) or (>1000 && <2000) won't work (for different reasons, obviously). What I'm asking is the most efficient way to do just that. I hate using 30 if statements, so I'd rather use the switch syntax. Is there anything that I can do?

推荐答案

当我看到其他答案中的解决方案时,我看到了一些我知道的事情其中性能差。我将把它放在一个评论,但我认为这是更好的基准和分享的结果。您可以自行测试。下面是我的结果(ymmv)在每个浏览器中最快的操作之后标准化(将1.0时间乘以标准化的值,得到以毫秒为单位的绝对时间)。

When I looked at the solutions in the other answers I saw some tings that I know where bad for performance. I was going to put it in a comment but I thought it was better to benchmark it and share the results. You can test it yourself. Below is my results (ymmv) normalized after the fastest operation in each browser (multiply the 1.0 time with the normalized value to get the absolute time in ms).


                    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 32位上使用以下版本执行的操作: 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。

Test where performed on Windows 7 32bit with the folowing versions: Chrome 21.0.1180.89m, Firefox 15.0, Opera 12.02, MSIE 9.0.8112, Safari 5.1.7. Node was run on a Linux 64bit box because the timer resolution on Node.js for Windows was 10ms instead of 1ms.

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

This is the fastest in all tested environments, except in ... drumroll MSIE! (surprise, surprise). This is the recommended way to implement it.

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



if-indirect



c $ c> switch-indirect-array 但是使用 if -statements,并且执行速度比 array 在几乎所有测试环境中。

if-indirect

This is a variant of switch-indirect-array but with if-statements instead and performs much faster than switch-indirect-array in almost all tested environments.

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



switch-immediate



这在所有测试环境中都相当快,实际上是MSIE中最快的。
当你可以做一个计算得到一个索引时,它工作。

switch-immediate

This is pretty fast in all tested environments, and actually the fastest in MSIE. It works when you can do a calculation to get an index.

switch (Math.floor(val/1000)) {
  case 0: /* do something */ break;
  case 1: /* do something */ break;
  ...
  case 29: /* do something */ break;
}



switch-range



这是比所有测试环境中最快的速度慢6到40倍,除了
在Opera,它需要大约1.5倍的时间。它是慢的,因为引擎
必须比较每个值两次的值。令人惊讶的是,与Chrome最快的操作相比,Chrome需要几乎40倍的时间才能完成,而MSIE只需要6倍的时间。但实际的时间差只有74ms,有利于MSIE在1337ms(!)。

switch-range

This is about 6 to 40 times slower than the fastest in all tested environments except for Opera where it takes about one and a half times as long. It is slow because the engine has to compare the value twice for each case. Surprisingly it takes Chrome almost 40 times longer to complete this compared to the fastest operation in Chrome, while MSIE only takes 6 times as long. But the actual time difference was only 74ms in favor to MSIE at 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;
}



switch-range2



这是 switch-range 的一个变体,但是每个案例只有一个比较,因此更快,但是除了Opera以外,它仍然很慢。 case语句的顺序很重要,因为引擎将以源代码顺序测试每个案例 ECMAScript262:5 12.11

switch-range2

This is a variant of switch-range but with only one compare per case and therefore faster, but still very slow except in Opera. The order of the case statement is important since the engine will test each case in source code order ECMAScript262:5 12.11

switch (true) {
  case (val < 1000): /* do something */ break;
  case (val < 2000): /* do something */ break;
  ...
  case (val < 30000): /* do something */ break;
}



switch-indirect-array


$ b b

在此变体中,范围存储在数组中。这在所有测试的环境中都很慢,在Chrome中很慢。

switch-indirect-array

In this variant the ranges is stored in an array. This is slow in all tested environments and very slow in 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;
}



array-linear-search


$ b b

这是数组中的值的线性搜索和具有固定值的开关
语句的组合。可能想使用这个的原因是当
值在运行时之前是未知的。它在每个测试环境中都很慢,在MSIE中花费的时间几乎是10倍。

array-linear-search

This is a combination of a linear search of values in an array, and the switch statement with fixed values. The reason one might want to use this is when the values isn't known until runtime. It is slow in every tested environment, and takes almost 10 times as long in MSIE.

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-binary-switch


$ b b

这是 array-linear-switch 的一个变体,但是使用二进制搜索。
不幸的是它比线性搜索慢。我不知道是否是我的实现或如果线性搜索更优化。也可能是键空间很小。

array-binary-switch

This is a variant of array-linear-switch but with a binary search. Unfortunately it is slower than the linear search. I don't know if it is my implementation or if the linear search is more optimized. It could also be that the keyspace is to small.

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或切换和立即数值。

Conclusion

If performance is important, use if-statements or switch with immediate values.

这篇关于大于/小于的switch语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆