OR运算(||)与inArray()的性能

时间:2012-05-07 08:38:49

标签: javascript jquery performance

假设您要检查用户在表单字段中输入的输入字符串。根据可能值列表检查此输入的最快方法是哪一种?

以下示例使用 jQuery

第一种方法:使用||

if (input == "firstValue" || input == "secondValue" || ... ) {
    ...
}

第二种方法:使用inArray()

if ($.inArray(input, array) >= 0) {
    ...
}

这两种方法之间是否存在显着差异?

4 个答案:

答案 0 :(得分:17)

您不想要最快但最易读的方式。那个in_array()(JavaScript:array.indexOf(value) >= 0)超过2或3个值。

性能差异可以忽略不计 - 虽然函数调用和数组创建肯定会有一些开销,但与昂贵的操作(例如文件访问,数据库访问,网络访问等)相比并不重要。所以最后没有人会注意到差异。

这里有一个简短的benchmark,每个都有100万次迭代:

5.4829950332642 - in_array, the array is recreated everytime
2.9785749912262 - in_array, the array is created only once
0.64996600151062 - isset(), the array way created only once and then the values were turned to keys using array_flip()
2.0508298873901 - ||

所以,最快,但仍然非常易读的方法就是这样。除非您只创建一次$arr并使用多次次,否则您无需使用in_array()

$arr = array_flip(array('your', 'list', 'of', 'values'));
if(isset($arr[$value])) ...

如果您 要求使用JavaScript(在这种情况下删除那些$前缀!),最佳解决方案是使用{{1} }:

Array.indexOf()

但是,并非所有浏览器都支持['a', 'b', 'c'].indexOf(value) >= 0 ,因此您可能希望使用例如来自Underscore.js的函数:

Array.indexOf()

jQuery也有这个功能:

_.contains(['a', 'b', 'c'], value)

最快的方法是使用对象和$.inArray(value, ['a', 'b', 'c']) 运算符,但对象定义的可读性低于数组定义:

in

这里是各种解决方案的JSPerf基准:http://jsperf.com/inarray-vs-or - 但是,在大多数情况下,相当大的性能差异可以忽略不计,因为您不会在循环中执行数百万次代码。

答案 1 :(得分:4)

答案是,取决于 ......

如果只有少数几种可能,请使用if (a || b || c)

如果最多可能有10个,请使用Array.indexOf()

请注意,对于上述两条建议,选择应取决于可读性,而不是真正的性能。

如果有(多个)更多,请使用密钥等于值的Object,然后您可以使用if (myVar in myKeyObj)。这应该是最差O(log n)表现。

答案 2 :(得分:2)

在执行javascript时,性能通常不是问题,通常是难以回答的问题。

在此示例中,解决方案之间的主要区别在于扩展。第一个解决方案将始终执行预定数量的比较,inArray解决方案会变得更糟,因为如果有更多值,它会比较更多。

然而我仍然在inArray,99.99%的机会表现真的无关紧要。您希望保持代码的可维护性,这一点更为重要。

答案 3 :(得分:2)

在大多数语言中,inArray()都是这样实现的:

function inArray(needle, haystack) {
  for (i = 0; i < length; i++) {
    if (haystack[index] == needle) {
      return true;
    }
  }

  return false;
}

如果你要展开那个循环,你最终会做

if (haystack[0] == needle) {
  return true;
} 
if (haystack[1] == needle) {
  return true;
}
if (haystack[3] == needle) {
  return true;
}
// and so on

可以压缩到

if (haystack[0] == needle || haystack[2] == needle || … ) {
  return true;
}

不改变引擎盖下发生的事情。


如果你反复不得不查找这样的东西,我建议你去了解地图。而不是

var haystack = ['hello', 'world', 'how', 'is', 'life'];
if (inArray("life", haystack)) {
  // …
}
你做了

var haystack = {'hello' : true, 'world' : true, 'how' : true, 'is' : true, 'life' : true};
if (haystack["life"]) {
  // …
}

要检查的元素越多,与数组相比,地图的执行效果就越好。