Javascript: эффективный доступ к данным
В своих предыдущих блогах о стеке вызовов и куче памяти я рассказывал, как хранятся данные и как к ним можно получить доступ. В этом блоге я буду визуализировать эффективность каждого метода хранения.
Эффективность стека вызовов
Стек вызовов — это контейнер хранения First-In-Last-Out. Это означает, что каждый раз, когда программа хочет получить доступ к переменной, она должна проверять последний элемент, добавленный в стек, прежде чем он сможет двигаться глубже.
В приведенном ниже примере, если программа хочет получить доступ к переменной friend, ей нужно будет проверить каждую переменную, хранящуюся в стеке над ней, прежде чем программа заглянет внутрь переменной. чтобы увидеть, какие примитивные данные существуют.
Для нашей программы требуется всего пять шагов для доступа к переменной friend, четыре проверки и одна оценка. Обычно это не занимает у программистов достаточно времени, чтобы беспокоиться об этом. Даже стеку вызовов с тысячами переменных все равно потребуется всего миллисекунды, чтобы вернуть значение. Итак, почему это важно?
Допустим, наша программа должна была вызывать одно и то же значение снова и снова? Если бы в нашей программе выполнялось множество сложных вычислений, требующих доступа к переменным в нижней части стека тысячи раз, увеличение времени проверки каждой переменной в стеке также умножилось бы. Вдруг миллисекунды превратятся в минуты.
Эффективность кучи
Сложные данные, такие как объекты, используют древовидную структуру, при этом каждый уровень дерева имеет собственный подстек. Метод доступа к примитивным данным, хранящимся в сложном объекте, можно увидеть ниже, когда мы пытаемся получить доступ к тому, может ли Джордан пить, вызывая result.jordan.canDrink.
Чтобы понять, что происходит, сначала в стеке выполняется поиск переменной result. Это первая переменная в стеке, поэтому она оценивается.
(2 шага)
Оценка указывает на кучу и сообщает ей вызвать переменную result. Если в куче есть несколько переменных, каждая из них будет оцениваться как подстек в следующем порядке:
- Целые числа в порядке возрастания
- Строки в возрастающем, хронологическом порядке или от старых к новым
- Символы в возрастающем, хронологическом порядке или от самого старого к самому новому
result — единственная переменная в куче, поэтому она сразу же находится и оценивается. Оценка указывает на подстек, который включает обе переменные jacob и jordan.
(4 шага)
Предположим, что jordan — самая младшая переменная, это будет означать, что сначала будет проверяться jacob, а затем jordan, которая затем будет оцениваться, указывая на другой подстек с переменными age и canDrink.
(7 шагов)
В этом вложенном стеке возраст оказывается старшей из двух переменных и сначала проверяется, а затем оценивается как истина.
(9 шагов).
Эффективное проектирование
В приведенном выше примере мы теряем несколько миллисекунд в процессе поиска и оценки, но что происходит, когда мы увеличиваем масштаб программы?
Допустим, у нас есть тысяча друзей, которых мы хотим каталогизировать. Если бы мы использовали только стек вызовов, у каждого друга были бы еще две дополнительные переменные, их возраст и могут ли они выпить, которые нужно было бы проверять, когда машина пытается доступ к данным.
Если наша программа использует правильно структурированный объект, мы можем ограничить количество переменных, которые должны быть проверены, и даже имена переменных могут быть общими из-за разницы в области видимости. В этой программе нам нужно будет искать только «имена друзей», прежде чем искать, могут ли они пить.
Поскольку мы классифицируем переменные и перемещаем их в подстек, мы убираем процесс проверки этих переменных при поиске конкретного друга, которого мы хотим проверить. Если у нас есть тысяча друзей, использование объектно-ориентированной структуры уберет более двух тысяч шагов.
Балансирующий акт
Не каждая программа выиграет от использования Heap, но понимание этих принципов поможет программистам создать эффективную основу для доступа к данным. Эта основа может повлиять на время ожидания сложных вычислений, поскольку доступ к переменным осуществляется сотни или тысячи раз.
Ресурсы
Порядок вызова подстека в куче согласно ES2015: