我想知道javascript中以下条件结构实现的性能。
方法1:
if(id==="camelCase"){
window.location.href = "http://www.thecamelcase.com";
}else if (id==="jsFiddle"){
window.location.href = "http://jsfiddle.net/";
}else if (id==="cricInfo"){
window.location.href = "http://cricinfo.com/";
}else if (id==="apple"){
window.location.href = "http://apple.com/";
}else if (id==="yahoo"){
window.location.href = "http://yahoo.com/";
}
方法2:
switch (id) {
case 'camelCase':
window.location.href = "http://www.thecamelcase.com";
break;
case 'jsFiddle':
window.location.href = "http://www.jsfiddle.net";
break;
case 'cricInfo':
window.location.href = "http://www.cricinfo.com";
break;
case 'apple':
window.location.href = "http://www.apple.com";
break;
case 'yahoo':
window.location.href = "http://www.yahoo.com";
break;
}
方法3
var hrefMap = {
camelCase : "http://www.thecamelcase.com",
jsFiddle: "http://www.jsfiddle.net",
cricInfo: "http://www.cricinfo.com",
apple: "http://www.apple.com",
yahoo: "http://www.yahoo.com"
};
window.location.href = hrefMap[id];
方法4
window.location.href = {
camelCase : "http://www.thecamelcase.com",
jsFiddle: "http://www.jsfiddle.net",
cricInfo: "http://www.cricinfo.com",
apple: "http://www.apple.com",
yahoo: "http://www.yahoo.com"
}[id];
可能方法3和4可能具有几乎相同的性能,但只是发布以确认。
答案 0 :(得分:60)
根据此JSBen.ch测试,switch
设置是所提供方法中最快的(Firefox 8.0和Chromium 15)。
方法3和方法4的速度稍慢,但几乎不可察觉。显然,if-elseif方法明显变慢(FireFox 8.0)。
在Chromium 15中的相同测试未显示这些方法之间的性能的显着差异。事实上,if-elseif方法似乎是Chrome中最快的方法。
我已运行测试用例again,另外还有10个条目。 hrefmap(方法3和4)显示出更好的性能。
如果你想在函数中实现compare方法,方法3肯定会胜出:将地图存储在一个变量中,稍后再引用这个变量,而不是重建它。
答案 1 :(得分:16)
您可以随时自行进行jsPerf测试。但是,通常查找表是访问数据的最快方式。在你的片段中,这将是(3)。此外,switch/case
几乎总是比if-else
更快。所以你的例子的顺序是
(3) - > (4) - > (2) - >的(1)强>
答案 2 :(得分:0)
if-else
vs switch
vs map of functions
vs class method dispatch
我想很多人都会问这个问题,基于 if-else、switch 或 map 的调节的性能,因为他们想知道如何最好地调节 逻辑 ,正如标题所暗示的,而不是简单的基于键的值查找。
My benchmark 与已接受答案中的不同,还纠正了一些缺陷(结果表底部的进一步解释):
测试分支逻辑。即条件执行流程,而不是简单的查找。
随机分支。在设置中生成随机的分支密钥序列。然后用相同的顺序测试每种方法。
分支结果不可预测。每个分支的逻辑结果对于其他分支是不一样的,对于同一个分支的后续执行也不一样。
有 11 个分支。对我来说,这个问题与那么多人更相关。如果数量少得多,则考虑除 if-else
或 switch
之外的任何其他内容都没有意义。
重用的结构在设置中初始化,而不是在基准代码块中。
这是我在 Safari/macOS 上得到的:
方法 | JSBench |
---|---|
if-else |
100 |
switch |
99+ |
map of functions |
~90 |
class method dispatch |
~85 |
我运行 same benchmark again with twice as many branches (22) 时希望看到地图取得进展,但得到了大致相同的结果(尽管 class method dispatch
的表现可能相对稍好一些)。如果我有时间,我会编写代码来生成基准代码,这样我就可以绘制各种分支计数的图表……但可惜我没有。
问题自己的示例代码以及 Rob W's answer 和 jAndy's answer 中使用的基准代码仅用于测试值查找。正如预期的那样,对于一小组键,这些基准测试显示的性能差异可以忽略不计;任何显着差异都是 JS 引擎的缺陷。他们没有证明条件逻辑的问题。
此外,正如一些人指出的,基准代码中还有其他缺陷:
仅当条件逻辑执行数千次时,性能才重要。在这种情况下,不会每次使用都重新初始化数据结构。
测试代码每次都采用相同的分支。这有两个问题:
它不反映平均成本(例如,对于 if-else 或 switch,较早的分支更便宜,后来更昂贵)。
编译时或 JIT 优化可能会将其优化掉,从而产生误导性的结果(因为在实际代码中,条件不会那么可预测)。
每个分支每次都产生完全相同的结果。而对于Rob W's benchmark,结果与输入相同!
当然,地图对于这种用法会表现得很好。这就是它们的设计目的!
如果您有条件逻辑,其中每个分支的逻辑每次都产生完全相同的结果,您应该考虑使用 memoization。
答案 3 :(得分:-1)
我想我会加上这个作为一个可能的考虑因素。我在这个问题上进行了研究...... http://davidbcalhoun.com/2010/is-hash-faster-than-switch-in-javascript
需要考虑不同的引擎和浏览器。