假设您要检查用户在表单字段中输入的输入字符串。哪一种方法是根据可能值列表检查此输入的最快方法?
以下示例使用jQuery。
第一种方法:使用||
if (input == "firstValue" || input == "secondValue" || ... ) {
...
}
第二种方法:使用inArray()
if ($.inArray(input, array) >= 0) {
...
}
这两种方法之间有什么显着差异吗?
假设您要检查用户在表单字段中输入的输入字符串。哪一种方法是根据可能值列表检查此输入的最快方法?
以下示例使用jQuery。
第一种方法:使用||
if (input == "firstValue" || input == "secondValue" || ... ) {
...
}
第二种方法:使用inArray()
if ($.inArray(input, array) >= 0) {
...
}
这两种方法之间有什么显着差异吗?
你不想要最快但最易读的方式。这就是in_array()
(JavaScript: array.indexOf(value) >= 0
) 超过 2 或 3 个值。
性能差异可以忽略不计——虽然函数调用和数组创建肯定有一些开销,但与文件访问、数据库访问、网络访问等昂贵的操作相比,这并不重要。所以最终没有人会注意到差异.
这是一个简短的基准,每个都有 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(在这种情况下摆脱那些$
前缀!),最好的解决方案是使用Array.indexOf()
:
['a', 'b', 'c'].indexOf(value) >= 0
然而,并不是所有的浏览器都已经支持Array.indexOf()
,所以你可能想使用 Underscore.js 中的函数:
_.contains(['a', 'b', 'c'], value)
jQuery 也有一个功能:
$.inArray(value, ['a', 'b', 'c'])
最快的方法是使用对象和in
运算符,但对象定义的可读性不如数组定义:
value in {'a':0, 'b':0, 'c':0}
这是各种解决方案的 JSPerf 基准测试:http://jsperf.com/inarray-vs-or -但同样,在大多数情况下,相当大的性能差异可以忽略不计,因为您不会在一次代码中执行数百万次环形。
答案是,这取决于...
如果只有几种可能性,请使用if (a || b || c)
.
如果可能多达 10 个,请使用Array.indexOf()
请注意,对于上面的两个建议,选择应该取决于可读性,而不是真正的性能。
如果有(很多)更多,请使用Object
与值相等的键,然后您可以使用if (myVar in myKeyObj)
. 这应该给出最差的O(log n)
性能。
执行 javascript 时,性能通常不是什么大问题,而且通常是很难回答的问题。
在此示例中,解决方案之间的主要区别在于缩放。第一个解决方案将始终进行预定数量的比较,inArray 解决方案的扩展性更差,因为如果有更多的值,它将进行更多的比较。
但是我仍然会选择 inArray,99.99% 的机会表现真的无关紧要。你想让你的代码保持可维护性,这更重要。
在大多数语言中,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"]) {
// …
}
必须检查的元素越多,与数组相比,地图的性能就越好。