Хранение ссылок на элементы DOM

Если рекурсия слишком глубокая, программе не хватает памяти стека. Это называется переполнением стека.

int modulo(int n, int m) 
{ 
    if (n < m) return n; 
    else return modulo(n - m, m); 
}

Например, modulo(1000000, 2) вызывает modulo(999998, 2), что вызывает modulo(999996, 2), и так далее, пока в конце modulo(0, 2) не будет 500001 активных функций modulo в стеке. Два целых числа, адрес возврата и указатель кадра, должны занимать не менее 16 байт на вызов функции в любой разумной системе. Всего 8 мегабайт стекового пространства, что обычно превышает максимальный размер стека.

Каждый вызов функции должен ждать результатов следующей функции, пока он не завершит свой расчет и не вернется. До его возвращения в стеке должны были храниться все переменные, параметры и адрес возврата. Адрес возврата - это место в программе, где программа должна возобновить работу после оператора return.

Эти вызовы заполняют стек до тех пор, пока не будет достигнут его максимальный предел и программа не завершится.

В некоторых случаях компилятор может преобразовать рекурсию в цикл. В этом случае, поскольку рекурсия находится в операторе return, она может просто goto перейти к началу функции, вообще не выполняя вызов. Это называется оптимизация хвостового вызова :

int modulo(int n, int m) 
{ 
    start:
    if (n < m) return n; 
    else {
       n -= m;
       goto start;
    }
}

Если бы вы включили оптимизацию (-O2 в clang или G ++ или режим выпуска в Visual C ++), не было бы сбоя, так как компилятор создал бы цикл вместо рекурсии. Чтобы избежать сбоя, просто включите оптимизацию.

Обратите внимание, что компилятор не обязан оптимизировать это, и не всегда может. Вот почему не рекомендуется иметь такую ​​глубокую рекурсию.

8
задан nickf 16 April 2009 в 01:16
поделиться

2 ответа

Я бы сохранил элемент; это имеет тенденцию делать код более понятным, когда вы не вызываете document.getElementById все время, и хотя в вашем случае вам может не потребоваться изменять идентификаторы или разрешать элементы без идентификаторов, это довольно распространенное желание сделать это.

( В отличие от apphacker, я бы не ожидал от этого значительного улучшения эффективности , так как getElementById имеет тенденцию быть довольно хорошо оптимизированным в браузерах.)

Есть ли какие-либо проблемы с производительностью, о которых я должен знать?

Ссылки от объектов JavaScript до объектов DOM сами по себе хороши, но когда объект DOM имеет ссылку на такой объект JavaScript (обычно через обработчик событий), вы получаете цикл ссылок. Это приводит к утечке памяти в IE6-7, поскольку он не освобождает зацикленные объекты. Для небольших простых приложений вам может быть все равно. Для сложных, долго работающих приложений вам, возможно, придется обойти эту проблему, например, путем направления каждого обработчика событий через карту / массив поиска, чтобы не было прямой ссылки из объекта DOM на реальный обработчик событий.

5
ответ дан 5 December 2019 в 20:18
поделиться

Сохранить элемент, а не идентификатор, внешний вид up работает медленно и дорого и спасает вас от вызова функции. Я думаю, что простой тест подтвердит это.

3
ответ дан 5 December 2019 в 20:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: