为了账号安全,请及时绑定邮箱和手机立即绑定

切换语句大于/小于

/ 猿问

切换语句大于/小于

偶然的你 2019-08-24 14:58:58

切换语句大于/小于

所以我想使用这样的开关语句:

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

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


查看完整描述

3 回答

?
45度呼吸

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

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

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

如果,即时

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

if (val < 1000) { /*do something */ } elseif (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 */ } elseif (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需要大约1.5倍的时间。它很慢,因为引擎必须为每种情况比较两次值。令人惊讶的是,与Chrome中最快的操作相比,Chrome完成此操作所需的时间要长近40倍,而MSIE只需要6倍的时间。但实际时差仅为74毫秒,有利于MSIE为1337毫秒(!)。

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-statements或switch使用立即值。


查看完整回答
反对 回复 2019-08-24
?
喵喵时光机
switch (Math.floor(scrollLeft/1000)) {
  case 0: // (<1000)
   //do stuff
   break;
  case 1: // (>=1000 && <2000)
   //do stuff;
   break;}

只有经常步骤才有效...


查看完整回答
反对 回复 2019-08-24
?
BIG阳

我讨厌使用30 if语句

我最近有同样的情况,这就是我解决它的方式:

之前:

if(wind_speed >= 18) {
    scale = 5;} else if(wind_speed >= 12) {
    scale = 4;} else if(wind_speed >= 9) {
    scale = 3;} else if(wind_speed >= 6) {
    scale = 2;} else if(wind_speed >= 4) {
    scale = 1;}

后:

var scales = [[4, 1], [6, 2], [9, 3], [12, 4], [18, 5]];scales.forEach(function(el){if(wind_speed > el[0]) scale = el[1]});

如果你设置“1,2,3,4,5”,那么它可以更简单:

var scales = [4, 6, 9, 12, 18];scales.forEach(function(el){if(wind_speed >= el) scale++});


查看完整回答
反对 回复 2019-08-24

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信