Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
569 views
in Technique[技术] by (71.8m points)

javascript - 切换语句大于/小于(Switch statement for greater-than/less-than)

so I want to use a switch statement like this:(所以我想使用这样的开关语句:)

switch (scrollLeft) { case (<1000): //do stuff break; case (>1000 && <2000): //do stuff break; } Now I know that either of those statements ( <1000 ) or ( >1000 && <2000 ) won't work (for different reasons, obviously).(现在我知道这些语句中的任何一个( <1000 )或( >1000 && <2000 )都不起作用(显然有不同的原因)。) 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.(我讨厌使用30 if语句,所以我宁愿使用switch语法。) Is there anything that I can do?(有什么我可以做的吗?)   ask by switz translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When I looked at the solutions in the other answers I saw some things that I know are bad for performance.(当我在其他答案中查看解决方案时,我看到一些我知道对性能有害的事情。)

I was going to put them in a comment but I thought it was better to benchmark it and share the results.(我打算将它们放在评论中,但我认为最好对它进行基准测试并分享结果。) You can test it yourself .(你可以自己测试一下 。) Below are 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).(下面是我的结果(ymmv)在每个浏览器中最快的操作之后归一化(将1.0时间乘以标准化值以获得以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 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 .(使用以下版本测试在Windows 7 32位上执行的操作: Chrome 21.0.1180.89mFirefox 15.0Opera 12.02MSIE 9.0.8112Safari 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.(节点在Linux 64位盒上运行,因为Node.js for Windows上的计时器分辨率是10ms而不是1ms。) if-immediate(如果,即时) This is the fastest in all tested environments, except in ... drumroll MSIE!(这是所有测试环境中最快的,除了...... 鼓乐 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(如果间接) 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.(这是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 switch-immediate(开关,立即) This is pretty fast in all tested environments, and actually the fastest in MSIE.(这在所有测试环境中都非常快,实际上是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(开关范围) 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.(这比所有测试环境中最快的速度慢6到40倍,除了Opera需要大约1.5倍的时间。) 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.(令人惊讶的是,与Chrome中最快的操作相比,Chrome完成此操作所需的时间要长近40倍,而MSIE只需要6倍的时间。) But the actual time difference was only 74ms in favor to MSIE at 1337ms(!).(但实际时差仅为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; } switch-range2(开关范围2) This is a variant of switch-range but with only one compare per case and therefore faster, but still very slow except in Opera.(这是switch-range一种变体,但每种情况只有一个比较,因此速度更快,但除了Opera之外仍然很慢。) The order of the case statement is important since the engine will test each case in source code order ECMAScript262:5 12.11(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; } 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.(这在所有测试环境中都很慢,而在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(阵列线性搜索) This is a combination of a linear search of values in an array, and the switch statement with fixed values.(这是对数组中值的线性搜索和具有固定值的switch语句的组合。) 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.(在每个测试环境中都很慢,在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-binary-switch(阵列二进制开关) This is a variant of array-linear-switch but with a binary search.(这是array-linear-switch的变体,但具有二进制搜索。) 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; } Conclusion(结论) If performance is important, use if -statements or switch with immediate values.(如果性能很重要,请使用if -statements或switch为立即值。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...