交换机与对象查找性能(因为 JSPerf 已关闭)

switch vs object lookup performance (since jsperf is down)

提问人:IMTheNachoMan 提问时间:6/9/2016 更新时间:6/28/2022 访问量:12706

问:

在我看来,在某些情况下,如果某个值等于某物,有两种方法可以做某事:开关或对象查找。

使用开关:

var value = ["Hello", "hi", "bYe", "die"][Math.floor(Math.random() * (4))];

switch (value.toLowerCase()) {
  case "hello":
    alert(value + "\n\n" + "hi");
    break;
  case "hi":
    alert(value + "\n\n" + "hello");
    break;
  case "bye":
    alert(value + "\n\n" + "no");
    break;
  case "die":
    alert(value + "\n\n" + "you shot me");
    break;
}

使用对象查找:

var value = ["Hello", "hi", "bYe", "die"][Math.floor(Math.random() * (4))];

var LOOKUP = {
  "hello": function(v) {
    alert(v + "\n\n" + "hi");
  },
  "hi": function(v) {
    alert(v + "\n\n" + "hello");
  },
  "bye": function(v) {
    alert(v + "\n\n" + "no");
  },
  "die": function(v) {
    alert(v + "\n\n" + "you shot me");
  },
};

LOOKUP[value.toLowerCase()](value);

我想知道哪个会有更好的性能?

这两种方法都会有任何不明显的问题/陷阱吗?

JavaScript 性能

评论

1赞 Felix Kling 6/9/2016
除了 jsperf 之外,还有其他方法可以分析代码:developers.google.com/web/tools/chrome-devtools/profile 或编写一个简单的 Node 脚本。

答:

20赞 Dan 6/22/2016 #1

原答案:查找表要快得多。

更新的答案 2020:这两种方法在现代浏览器中的性能几乎相同,switch 语句比查找表快 20-30%。

不久前我也有同样的问题。如果 jsperf 复活了,这就是链接。https://jsperf.com/if-switch-lookup-table/10

编辑:工作基准 https://jsben.ch/JYZLQ

评论

0赞 Capuchin 4/6/2017
你的标题不是错了吗?开关看起来像查找,反之亦然?
1赞 Capuchin 4/6/2017
确实,这似乎是一个错误的答案,查找速度较慢
1赞 Esko 4/6/2017
switch事实上,至少在 OSX 上的最新 Chrome 和 Safari 上更快,我想这同样适用于所有甚至有点现代的浏览器。
6赞 Phugo 2/15/2019
好吧,这个测试每次都会重新创建对象。它显然更慢。在实际场景中,只需定义一次常量对象,然后仅在查找时重复。我创建了另一个测试,其中还包括 jsben.ch/HoDxa TL;DR 对象实际上在 Firefox 上更快,但在 Chrome 上结果保持不变Map
2赞 Guillermo Ares 5/18/2020
这是另一个测试:jsben.ch/FLez6。以@Phugo为基础。摆脱了一堆扭曲比较的东西(主要是函数调用)。还进行了“在函数内部切换”测试,以防有一些我不知道的编译器自动优化。这四种方法似乎或多或少地相等,尽管开关版本似乎稍快一些。我认为这归结为在您的代码中看起来最好的内容。
1赞 Deepkamal 6/28/2022 #2

它是时间复杂度和空间复杂度之间的权衡, 想象一个有 10000 个案例的开关,所以你会创建一个有 10000 个键的对象,整个对象必须加载到内存/缓存中进行查找,而对于开关案例,它将根据条件从一个指令跳到另一个指令,

我个人更喜欢对象键查找而不是开关大小写,因为它的代码更易于维护,并且设计模式也更可扩展。