OR运算(||)与inArray()的性能
假设您要检查用户在表单字段中输入的输入字符串。 对于可能的值列表,哪一个是检查此输入的最快方法?
以下示例使用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()
,因此您可能希望使用例如Array.indexOf()
的函数:
_.contains(['a', 'b', 'c'], value)
jQuery还有一个function:
$.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"]) { // … }
必须检查的元素越多,与数组相比,地图的执行效果越好。