Точное соответствие и хэши. Технологии будущего. Оптимизация структуры веб-страниц
Выбор в зависимости от строки
Точное соответствие и хэши
Итоговая таблица
Давайте теперь рассмотрим следующий вариант регулярного выражения: /a|b|c/. В этом случае нам нужно проверить в заданной строке наличие одного из возможных вариантов (или равенство строки этому варианту). В случае точного соответствия быстрее регулярного выражения (на 50%) будет проверка строки как ключа какого-либо хэша:
var hash = {'a':1, 'b':1},
str = 'a';
if (h[str]) {
...
}
Быстрее (на 20%) такого хэша будет только точная проверка строки на определенные значения:
if (ss === 'a' || ss === 'b'){
...
}
Если рассмотреть 3 конструкции: вложенный if, switch с соответствующим значениям и проверка значений в хэше, - то стоит отметить следующую интересную особенность. При небольшом уровне вложенности if (если всего значений немного, или мы очень часто выходим по первому-второму значению), конструкции if и switch обгоняют по производительности хэш примерно на 10%. Если же у нас значений много, и они все примерно равновероятны, то хэш отрабатывает в общем случае быстрее уже на 20%. Это в равной степени относится как к установлению значений переменных, так и к вызову функций. Поэтому для создания ветвления с вызовом функций лучше всего использовать именно хэш.
При анализе CSS-селектора можно выделить несколько подзадач, описываемых как «проблема выбора»: Ветвление для простого случая выполнено при помощи проверки входной строки через test:
if (/^[\w[:#.][\w\]*^|=!]*$/.test(selector)) {
...
} else {
...
}
Ветвление для простейшего случая (когда нам нужно выбрать по идентификатору или по классу). Поскольку всего значений у нас 5, и 3 из них относительно равновероятны (выбор по классу, по идентификатору или по тегу), то используется switch:
switch (firstLetter) {
case '#':
...
break;
case '.':
...
break;
case ':'
...
break;
case '[':
...
break;
default:
...
break;
} Абсолютно аналогичную картину мы наблюдаем для выбора правильного отношения «родитель-ребенок» (>, +, ~, ): тут тоже только switch:
switch (ancestor) {
case ' ':
...
break;
case '~':
...
break;
case '+':
...
break;
case '>':
...
break;
}
Наконец, выбор соответствующей проверочной функции для child-модификаторов (first-child, last-child, nth-child, и т.д.) и выбор проверочной функции для атрибутов (~=, *=, = и т.д.) осуществляется уже через специальные хэши:
_.attr = {'': ... , '=': ... , '&=': ... , '^=': ... ... }