为什么第三种选择比正则表达更好?

时间:2010-10-15 18:37:09

标签: javascript performance

我认为正则表达式非常快,第三种选择令人困惑。你觉得怎么样?

http://jqfundamentals.com/book/ch09s12.html

// old way
if (type == 'foo' || type == 'bar') { ... }

// better
if (/^(foo|bar)$/.test(type)) { ... }

// object literal lookup 
if (({ foo : 1, bar : 1 })[type]) { ... }

7 个答案:

答案 0 :(得分:6)

我会谦卑地不同意丽贝卡·墨菲(Rebecca Murphey)并为简单而投票,这是第一种选择。

我认为正则表达式很快
机器代码甚至更快,但我们不使用它。

第三个​​选项令人困惑
如果你不熟悉这个技巧,那只会让人感到困惑。 (对于那些不习惯看正则表达式来比较两个字符串的人来说,第二个选项会更加令人困惑。)

答案 1 :(得分:5)

我刚刚做了一个基本的基准,我老实说不确定她是如何得到这些结果的...... http://jsbin.com/uzuxi4/2/edit

正则表达式似乎是最好的,但在所有现代浏览器中,第一个是迄今为止最快的。最后一个是极其缓慢的。我理解三者之间的复杂性理论,但在实践中,似乎并不正确。

更不用说第一个也具有最佳可读性的事实,它似乎也是最快的。我甚至嵌套循环来利用文字表或常量的任何浏览器缓存(无济于事)。


修改 看来,当明确创建一个对象时,她确实是正确的,但是:http://jsbin.com/uzuxi4/4/edit

function __hash() {
  ...

  var type = 'bar';
  var testobj = { foo : 1, bar : 1 };
  var c = 0;
  for (i = 0; i < 1000; i++) {
    if (testobj[type]) {
      for (j = 0; j < 10000; j++) {
          if (testobj[type]) { c++; }
      }
    }
  }

  ...
}

我们看到,一旦对象有内部参考,寻道时间就会下降到大约500毫秒,这可能是一个平台。对象键查找可能是较大数据集的最佳选择,但实际上我并不认为它是日常使用的可行选项。

答案 2 :(得分:2)

  1. 第一个选项涉及 可能是两个字符串比较
  2. 第二个选项每次都涉及一次解析。
  3. 第三个选项执行字符串的简单哈希,然后查看哈希表 在这种情况下,就需要完成的工作量而言,这是最有效的。
  4. 第三个选项也比其他两个选项更好地扩展,因为添加了更多替代字符串,因为前两个是O(n),第三个是平均情况下的O(1)。

    如果我们想谈论哪个选项更漂亮/更易于维护,那就是一个完全独立的对话。

答案 3 :(得分:1)

第一种情况应该用===来完成以避免任何类型强制,但是根据你需要检查它的替代数量可以变成O(N),但是根据你的代码大多数JS引擎将能够进行简单的指针检查以进行比较。

在第二种情况下,您使用RegExp,而RegExps非常快,对于简单的相等决策,它们往往比更直接的相等比较慢。像你这样的简单字符串比较可能是现代JS引擎中的指针比较,但是如果使用正则表达式,则regexp 必须读取每个字符。

第三种情况比较棘手 - 如果你有很多值要检查它可能会更快,特别是如果你缓存对象而不是重复重新创建它,因为它只是一个哈希查找 - 确切的性能查找取决于引擎。

我怀疑switch语句会击败对象文字案例。

出于好奇,我做了一个测试(你可以看到here),最快的方法(至少每晚在webkit中)似乎是一个switch语句,接着是if,后跟对象, regexp的最后一次。

答案 4 :(得分:1)

只是想在这里权衡一下,并提醒大家这是一本开源书籍,有许多人的贡献!实际上,正在讨论的部分是基于社区成员提供的内容。如果您有改进该部分的建议,请务必在存储库上打开一个问题,或者更好的是,分叉回购并向我发送拉取请求:)

也就是说,我刚刚设置了一个jsPerf测试(http://jsperf.com/string-tests),至少在Chrome中,结果与本书的内容相反。我已经在这本书上打开了一个问题,并将在不久的将来尝试解决这个问题。

最后,有两件事:

  • 我想回应另一位评论者所说的内容:性能优化很有趣,虽然有一些确实很重要,但很多都没有。重要的是要了解这样的差异有多少 - 或者很少 - 。
  • 我也想回应这位评论者,他说,基本上,可读性是在旁观者的眼中。对一个人来说困惑的事情可能对另一个人来说非常清楚。我相信我们应该努力争取可读性,但我认为这是一种快乐的媒介。读起来对我来说有点令人困惑的代码让我看到了很多很棒的技巧;我讨厌如果它已经写好了,那么我当时的完整新词就能理解它。

答案 5 :(得分:0)

使用哈希查找优化对象文字查找,只需要一次逻辑检查而不是n。在较长的列表中,您也不必重复“类型==”数万次。

答案 6 :(得分:0)

为了简单和可读性,第一次将赢得每次。它可能不会那么快,但除非它处于严重运行的循环中,否则谁会关心。

好的编译器应该优化这样的事情。