javascript - 大于/小于的 switch 语句

标签 javascript jquery comparison switch-statement

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

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

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

最佳答案

当我查看其他答案中的解决方案时,我看到了一些我知道对性能不利的事情。我打算将它们放在评论中,但我认为最好对其进行基准测试并分享结果。您可以 test it yourself .以下是我在每个浏览器中以最快速度运行后标准化的结果 (ymmv)。
这是 2021-MAY-05 的结果


测试
Chrome 合金
火狐
歌剧
边缘
勇敢的
节点


1.0 次
15 毫秒
14 毫秒
17 毫秒
17 毫秒
16 毫秒
14 毫秒

如果立即
1.00
1.00
1.00
1.00
1.00
1.00

如果间接
2.20
1.21
2.06
2.18
2.19
1.93

立即切换
2.07
1.43
1.71
1.71
2.19
1.93

开关量程
3.60
2.00
2.47
2.65
2.88
2.86

开关范围2
2.07
1.36
1.82
1.71
1.94
1.79

开关间接阵列
2.93
1.57
2.53
2.47
2.75
2.50

阵列线性开关
2.73
3.29
2.12
2.12
2.38
2.50

阵列二进制开关
5.80
6.07
5.24
5.24
5.44
5.37


2021 年的测试在 64 位 Windows 10 和以下版本上执行:Chrome 90.0.4430.212、Firefox 89.0b13、Opera 76.0.4017.123、Edge 90.0.818.62、Brave 1.24.85 和在 Node (16) 下运行的 WSL (W)
Apple 没有为 Windows 更新 Safari,所以它仍然是 5.1.7。我在这次测试中将其更改为 Brave。
以下是 2012 年 9 月 4 日的结果,用于历史比较:


测试
Chrome 合金
火狐
歌剧
微信公众平台
苹果浏览器
节点


1.0 次
37 毫秒
73 毫秒
68 毫秒
184 毫秒
73 毫秒
21 毫秒

如果立即
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


2012 年的测试在 32 位 Windows 7 和以下版本上执行:Chrome 21.0.1180.89m、Firefox 15.0、Opera 12.02、MSIE 9.0.8112、Safari 5.1.7。 Node 在 Linux 64 位机器上运行,因为 Node for Windows 上的计时器分辨率是 10 毫秒而不是 1 毫秒。
如果立即
这是所有测试环境中最快的方法,除了...鼓声 MSIE! (惊喜,惊喜)。
这是实现它的推荐方法。

if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
如果间接
这是 switch-indirect-array 的变体但与 if -statements 而不是,并且在所有经过测试的引擎中都更快。
2021 年,它比最快的测试慢 20-120%(2012 年:0-280%)。 Chrome 2021 (2.20) 比 2012 (1.2) 需要更长的时间
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
立即切换
当您可以进行计算以获取索引时,这会起作用。
2021 年,它比 if-immediate 慢 40-120%(2012 年:0-180%) ,除了在 MSIE 中它实际上是最快的。
switch (Math.floor(val/1000)) {
  case 0: /* do something */ break;
  case 1: /* do something */ break;
  ...
  case 29: /* do something */ break;
}
开关量程
它很慢,因为引擎必须为每种情况比较两次值。
在 2021 年,它比最快的测试慢 1-2.6(2012 年:1.6-38)倍。
Chrome 从 38 到 3.6 的改进最大,但仍然是最慢的测试引擎。
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 的变体但每个案例只有一个比较,因此更快。
case 语句的顺序很重要,因为引擎将按源代码顺序测试每个 case ECMAScript 2020 13.12.9
在 2021 年,它比最快的测试慢 36-107%,但在 2012 年,它慢了 1-31 倍。本次测试中表现最差的依然是Chrome,但从32倍提升到了2倍。
switch (true) {
  case (val < 1000): /* do something */ break;
  case (val < 2000): /* do something */ break;
  ...
  case (val < 30000): /* do something */ break;
}
开关间接阵列
在这个变体中,范围存储在一个数组中。
2021 年,它比最快的测试慢 57-193%(2012 年:3-35 倍)。
所有测试引擎的性能都有所提高,虽然 Chrome 仍然是最慢的,但它已从 35 提高到 2.93。
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;
}
数组线性搜索
在这个变体中,范围存储在一个数组中。
2021 年,它比最快的测试慢 57-193%(2012 年:3-35 倍)。
所有测试引擎的性能都有所提高,虽然 Chrome 仍然是最慢的,但它已从 35 提高到 2.93。
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 的变体但是使用二进制搜索。
不幸的是,它比线性搜索慢。我不知道是我的实现还是线性搜索更优化了。也可能是键空间太小。
在 2021 年,这要慢 4-5(2012 年:4-16)倍。 请勿使用 .
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 -声明或 switch ,具有即时值。

关于javascript - 大于/小于的 switch 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6665997/

相关文章:

javascript - 从 InnerHtml 添加链接按钮

javascript - 如何将另一个网页的 div 而不是整个页面加载到我的网页中?

javascript - 如何使用事件处理程序创建 5 个 JQuery AJAX 调用?

jquery - 使用 Jquery Ajax 将模型从 View 传递到 Controller

c# - 为什么这个 DirectoryInfo 比较不起作用?

JavaScript:返回最大数字

javascript - 基于自定义数组顺序的 tinysort 排序 div

javascript - 如何在JS Cookie中设置cookie的过期日期(以秒为单位)

Javascript裁剪图像客户端

string - 将字符串与一组字符串进行比较的最有效算法