Производительность Javascript: Как происходит цикл через массив и проверка каждого значения быстрее, чем indexOf, поиск и совпадение?
Это стало для меня огромным сюрпризом, и я хотел бы понять этот результат. Я сделал тест в jsperf, который в основном должен взять строку (это часть URL-адреса, которую я хотел бы проверить) и проверок для присутствия 4 элементов (которые фактически присутствуют в строке).
Он проверяется 5 способами:
- plain indexOf;
- Разделите строку, затем indexOf;
- поиск регулярных выражений;
- регулярное выражение;
- Разделите строку, проведите цикл по массиву элементов, а затем проверьте, соответствует ли кто-либо из того, что она должна соответствовать
К моему огромному удивлению, номер 5 является самым быстрым в Chrome 21. Это то, что я не могу объяснить.
В Firefox 14 простой indexOf является самым быстрым, я могу поверить.
Ответы
Ответ 1
Я также удивлен, но Chrome использует v8, высоко оптимизированный механизм JavaScript, который тянет всевозможные трюки. И у ребят из Google, вероятно, есть самый большой набор JavaScript для проверки производительности их реализации. Поэтому я предполагаю, что это происходит:
- Компилятор замечает, что массив является строковым массивом (тип можно определить во время компиляции, не требуется проверка времени выполнения).
- В цикле, поскольку вы используете
===
, можно использовать встроенные коды op для сравнения строк (repe cmpsb
). Таким образом, никакие функции не вызываются (в отличие от любого другого тестового примера)
- После первого цикла все важные (массив, строки для сравнения) находятся в кэшах процессора. Locality rulez все они.
Все другие подходы требуют вызова функций, и локальность может быть проблемой для версий regexp, поскольку они создают дерево синтаксического анализа.
Ответ 2
Я добавил еще два теста: http://jsperf.com/finding-components-of-a-url/2
Единственный regExp работает быстрее (в Chrome). Также литералы regExp быстрее, чем строковые литералы, преобразованные в RegExp.