Перебор во фронтенде работает так, а эффективность супер высокая 🚀! легко быть побежденным

внешний интерфейс JavaScript
Перебор во фронтенде работает так, а эффективность супер высокая 🚀! легко быть побежденным

Случайно я нашлаИнтерфейсное перечислениеновый геймплей. Сначала я растерялся и подумал: «Что это?»

Замедлившись, он воскликнул: «Изысканно! Ниуби! Высокая эффективность!»

Я попробовал использовать его в проекте компании, и я действительно почувствовал, что эффективность выполнения программы стала быстрее (конечно, должны быть психологические намеки).

эта неделяCode ReviewКогда коллеги были в шоке:

Давайте посмотрим, что это за игра!

1. Определение перечисления

/**
 * SKILLS:面试者的技能枚举
 **/
const SKILLS = {
  CSS: 1 ,
  JS: 1 << 1,
  HTML: 1 << 2,
  WEB_GL: 1 << 3
}

Определение перечисления выглядит обыденным, но немного странным, не так ли?

пожалуйста, объясни:

<<символjsпобитовые операторы в ,1 << Nозначает:поставь цифры1переместить биты влевоNнемного.

1 << 1 // 2
// 二进制:1 => 10
1 << 2 // 4
// 二进制:10 => 100
...
1 << N // 2的N次方

Во-вторых, использование перечисления

Мы определили перечисление, как в «Шаге 1», так как же его использовать?

Предположим сценарий: когда мы берем интервью у фронтенд-одноклассника, мы постоянно будем отмечать, какие у него навыки.Процесс добавления оценок выглядит следующим образом:

let skills = 0
// 增加一项他会的技能
function addSkill(skill) {
  skills = skills | skill // 加上
}

addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13

После завершения добавления умений нам необходимо потратить те умения, которые есть у этого человека в других местах.Процесс расходования выглядит следующим образом:

// 判断他是否会 CSS
SKILLS.CSS & skills // 1 (0 代表不会,非0代表会)

// 判断他是否会 JS
SKILLS.JS & skills // 0 (0 代表不会,非0代表会)


// 判断他是否会 HTML 且会 WebGl
SKILLS.HTML & skills && SKILLS.WEB_GL & skills // 8 (0 代表不会,非0代表会)

// 判断他是否会 JS 或会 HTML
SKILLS.JS & skills || SKILLS.HTML & skills

В ПОРЯДКЕ! Доступны базовые способности.

Некоторые студенты спросят: «Какие у него преимущества? Читабельность такая плохая!»

Плюсы конечно есть, плюсы такие: эффективенВор высокий!

3. Сравнение эффективности

Чтобы проверить его «насколько эффективно», я написал два общих «контрольных» письма для проверки.

Общий метод записи 1: воспроизведение массива

let skills = []
function addSkill(skill) {
  if (!skills.includes(skill)) { // 判断技能术里是否有该技能
    skills.push(skill)
  }
}

addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13

skills.includes(SKILLS.CSS)
skills.includes(SKILLS.JS)
skills.includes(SKILLS.HTML) && skills.includes(SKILLS.WEB_GL)
skills.includes(SKILLS.JS) || skills.includes(SKILLS.HTML)

Таким образом, массив используется для хранения перечисления навыков, а затемarr.includes()метод, чтобы определить, было ли сохранено перечисление.

Обычное написание два:Mapиграть в

let skills = {}
function addSkill(skill) {
  if (!(skills[skill])) { // 判断技能术里是否有该技能
    skills[skill] = true
  }
}
addSkill(SKILLS.CSS) // 1
addSkill(SKILLS.HTML) // 5
addSkill(SKILLS.WEB_GL) // 13

skills[SKILLS.CSS]
skills[SKILLS.JS]
skills[SKILLS.HTML] && skills[SKILLS.WEB_GL]
skills[SKILLS.JS] || skills[SKILLS.HTML]

Этот метод через{ [value]: true }способ сохранить перечисление, а затем передатьmap[value]способ получить значение, чтобы определить, было ли сохранено перечисление.

сравнить результаты

Угадайте, каковы будут рейтинги эффективности трех способов?
Результат выглядит следующим образом:
Самая быстрая группа: группа битовых операций (способ воспроизведения, рекомендуемый в этой статье)

1,1 миллиарда выполнений в секунду

Второе место: игра с массивом

31,24 миллиона выполнений в секунду

Самая медленная группа:Mapиграть в

9,52 миллиона выполнений в секунду

Адрес варианта использования:Это Mercedes-Benz What/4OK и люди 97 его 9/…

Заинтересованные друзья могут посетить ссылку выше для самопроверки.

Согласно анализу результатов,最快и最慢даже между2-3разница на уровне данных.

В-четвертых, принципиальный анализ (почему так быстро!)

Почему «формула битовой операции», рекомендованная в этой статье, настолько эффективна? Как он выполняет вышеуказанные функции с помощью битовых операций?

4.1 Принцип определения

Это должно быть изJavascriptГоворя о формате данных среднего целого числа, целое число со знаком использует 31 бит для представления значения целого числа, а32Биты представляют знак целого числа,0представляет собой положительное число,1представляет отрицательное число. Диапазон значений[-2^31,2^31-1], то есть [-2147483648, 2147483647].如图所示Когда мы определяем перечисления, каждое перечисление занимает двоичное значение в другом бите.
Поэтому этот метод подходит только дляМеньше или равно 31 пункту перечисленияместо действия.

4.2 Принцип хранимой стоимости

Почемуskills = skills | skill Этот код может представлятьсуществуетskillsДобавлен элемент перечисления в?
|даJavascriptПобитовые операторы в:или.
когда два значения|В ходе операции сравнивается каждый бит, и по любому одному биту, если оба числа равны.0, то результат0; остальные результаты1;
Например:

1 << 1 | 1 << 2 // 010 | 100
// 结果为 110,即数字:6

1 | 1 << 3 // 0001 | 1000
// 结果为 1001,即数字:9

Поэтому до тех пор, пока выполнениеskills = skills | skill , в результатеskillДолжен быть соответствующий1.

4.3 Принцип ценности

ПочемуSKILLS.CSS & skillsвозвращение非0значение, может представлятьskillsсодержитSKILLS.CSS? Иначе не включает?
&даJavascriptОператоры в:и. когда два значения&Во время операции каждый бит сравнивается, и если два числа в любом одном бите равны1, то результат1; остальные результаты0;
Например:

1 & 9 // 0001 & 1001 = 0001 (1)

2 & 8 // 0010 & 1000 = 0000 (0)

следовательно,SKILLS.CSS & skillsвозвращение非0значение, его можно определитьskillsдолжен существовать вSKILLS.CSS.

5. Кто его использует? (Ю Юси: Это здесь)

Где я видел вышеуказанное использование?
Да, это изvue3видно в исходном коде. Адрес источника:GitHub1 — это .com/v UE JS/core/…

В этом исходном кодеvue3Определять перечисления таким образом, служебные перечисления, очень полезно.
ShapeFlagsПеречисление определяется как:

export const enum ShapeFlags {
  ELEMENT = 1,
  FUNCTIONAL_COMPONENT = 1 << 1,
  STATEFUL_COMPONENT = 1 << 2,
  TEXT_CHILDREN = 1 << 3,
  ARRAY_CHILDREN = 1 << 4,
  SLOTS_CHILDREN = 1 << 5,
  TELEPORT = 1 << 6,
  SUSPENSE = 1 << 7,
  COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,
  COMPONENT_KEPT_ALIVE = 1 << 9,
  COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT
}

Заканчивать

я春哥.
я люблюvue.js , ElementUI , Element PlusЧто касается стека родственных технологий, то моя цель — поделиться с вами самыми практичными и полезными моментами знаний, надеюсь, каждый сможет пораньше уйти с работы, быстро закончить работу и успокоиться.

ты сможешьНаггетсПодписывайтесь на меня:春哥的梦想是摸鱼, также доступный впубликанайди меня в:前端要摸鱼.
Надеюсь, вы все станете сильнее в 2022 году.