嵌套“开关” javascript 中的情况:有速度优势吗?
这里有新手问题:我有一个包含大量字符串的“开关”。像这样按字母顺序拆分是否有速度优势?
switch(myString.substring(0,1)){
case "a" : switch(myString){
case "a string beginning with a" : runCode(); break;
case "another string beginning with a" : runCode(); break;
} break;
case "b" : switch(myString){
case "by golly another string" : runCode(); break;
case "blimey - hundreds of strings" : runCode(); break;
//... etc
或者脚本语言是否会读取每一行,只是为了找到右括号?
newbie question here: I have a 'switch' containing numerous strings. Is there a speed advantage in splitting it alphabetically, like this?
switch(myString.substring(0,1)){
case "a" : switch(myString){
case "a string beginning with a" : runCode(); break;
case "another string beginning with a" : runCode(); break;
} break;
case "b" : switch(myString){
case "by golly another string" : runCode(); break;
case "blimey - hundreds of strings" : runCode(); break;
//... etc
Or does a scripted language read every line anyway, just to find the closed brackets?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是和不是。您会看到最小的速度增益,但不值得因这种结构而损失代码可读性。 switch 语句就像一个巨大的 if-else 语句块。它必须从一种情况转到另一种情况,直到找到它要查找的内容,就像与其等效的 if-elseif-else 结构一样。因此,您所做的就是帮助它跳过一些条件。对于大多数开发人员来说,嵌套的 switch 语句(尤其是这里编写的方式)的可读性不如直接的 if-elseif-else 层次结构。
Yes and no. You'd see a minimum speed gain, but not worth the code readability lost from this sort of structure. A switch statement is like a giant block of if-else statements. It has to go from one case to another until it finds what it's looking for, just like with the if-elseif-else structure equivalent to it. Thus all you're doing is to helping it skip over a handful of conditions. The nested switch statements, especially the way written here, are less readable for most developers than a straight up if-elseif-else hierarchy.
我认为你不应该介意这样的优化。我想说最好创建一个包含要执行的函数的对象,这样您就不需要过多的查找代码,而只需要这样的代码:
然后您可以仅使用此执行,而不是
switch
es 位于switch
es 内。它会在内部查找正确的函数,我真的认为这比自己做这样的事情更快:I don't think you should mind such optimization. I would say it's better to create an object with the functions to be executed, so that you don't need exessive lookup code, but just something like this:
Then you can execute with only this, instead of
switch
es insideswitch
es. It will look up the correct function internally, which I really think is faster than doing such things yourself:我还没有在 JS 版本上运行基准测试,但我知道在 PHP 中,使用 switch 与 if/else 相比有一点缺点,但差异可以忽略不计,并且在某些情况下,你在可读性/可维护性方面获得了速度上的损失(恕我直言)。
也就是说,我不相信你会在这里获得任何速度上的收获,除非你更有可能得到 a、b、c 结果而不是 x、y、z 结果。在评估 case 语句时,解析器将评估每个 case 直到找到匹配项,然后深入到该代码。
因此,如果您的答案比其他答案出现得更频繁,并将其放在最前面,从技术上讲,这将节省评估时间,但我认为节省的时间可以忽略不计。也就是说,对其进行数千次基准循环可能会显示出微秒级的差异。我懒得去实际测试,但这是我最好的猜测。
通常会避免使用 Nest switch 语句,因为它们不太漂亮并且难以阅读,这可能会导致错误和/或让同事感到沮丧。 :)
I haven't run benchmarks on the JS versions, but I know in PHP there is a slight disadvantage in using switch vs. if/else but the difference is negligible and in certain conditions you gain in readability/maintainability what you lose in speed (imho).
That said, I don't believe you'd gain anything in speed here unless you're more likely to have a,b,c results than x,y,z results. When evaluating the case statements the parser will evaluate each case until it finds a match and then descend into that code.
So if you have answers that come up more frequently than others and put those to the top it would technically save time in evaluating, but I think the time saved would be negligible. That is, a benchmark loop over it a couple thousand times would probably show microsecond differences. I'm too lazy to actually test that, but that's my best guess on it.
And nest switch statements are generally shunned as they're not very pretty and can be hard to read, which can introduce errors and or frustrated coworkers. :)
我想正确的答案可以通过经验测量——并且可能因 JavaScript 执行引擎而异。
基本上我们需要看看脚本编译可以用伪代码编译成什么最好的情况。
最坏的情况将是一组天真的连续字符串比较 - 即它顺序评估每个案例标签进行字符串比较 - 考虑到过去几年的所有速度声明,我怀疑任何主要引擎都会这样做,除非案例标签的数量很少(比如 2 或 3)。
对于较大数量的 case 标签,最佳的执行速度是引擎首先创建所有 case 标签的哈希表(在脚本加载时完成一次),然后在执行 switch 语句时计算输入并查找一组可能的目标值以进行最终字符串比较。
如果执行引擎这样做,那么 switch 语句的嵌套实际上会使所花费的时间加倍,从而降低执行速度。
因此,一般来说,对于现代 javascript 引擎(浏览器中使用的引擎),相信系统会做正确的事情,而不会生成不可读的代码 - 对于旧的和晦涩的 javascript 引擎(使用服务器端的不是 Node.JS 的引擎)测试一下什么你做。
I guess the correct answer could be empirically measured -- and could vary from one JavaScript Execution Engine to another.
Basically we need to look at what the best case the compilation of the script could be compiled to in terms of pseudo code.
Worst case would be a naive sequential set of string compares -- i.e. it sequentially evaluates each case lable doing a string compare -- With all the speed claims over the past few years, I doubt that any of the major engines would do this, unless the number of case lables are few (say 2 or 3).
For lager number of case label, the best execution speed would be for the engine to first create a hash table of all the case labels (done once when the script loads), and then whent the switch statement is executed, calculate the hash value of the input and lookup a set of possible target values for final string compare.
IF the execution engine does this, than the nesting of the switch statement would actually double the time taken -- and hence slowing the speed of execution.
So generally, for modern javascript engines (those used in browsers), trust the system to do the right thing without making unreadable code -- for old and obscure javascript engines (the ones used server side which are not Node.JS) test out what you do.