Комментарии 29
Если вам кажется необходимым перевести какой-либо материал по программированию, которого ещё не было на Хабре — пишите в личку.
+6
Ооочень полезная статья. К прочтению.
0
После прочтения ещё будет не лишним поглядеть доклад уже упомянутого в посте Вячеслава Егорова — www.youtube.com/watch?v=65-RbBwZQdU
+4
Что-то я сомневаюсь, что картинка со сравнением быстродействия массивов подписана правильно. Скорее всего там всё-таки не число операций в секунду, а время выполнения и, соответственно, чем больше, тем хуже. А значит и вывод сделанный из картинки — не верен.
+1
это jsperf.com'овые графики, он все выражает в операциях в секунду.
0
Я вижу, что это jsperf, поэтому не знаю, почему закралась ошибка, но предпочитаю верить своим глазам и логике. Да и любой желающий может сходить по имеющейся в тексте ссылочке на тот же jsperf и провести тесты самостоятельно, чтобы убедиться в том, что результаты противоположны. Например, у меня для chrome.39 пустой массив выдал 30 op/sec, а предзаполненный 133 op/sec. Для firefox.35 аналогично 81/87, opera.12 — 51/54, safari.5 — 45/46
Но можно и просто увидеть нелогичность картинки — если ей верить, то у всех браузеров с появлением новых версий производительность падает. Иногда так бывает, но так не может быть для всех браузеров.
Но можно и просто увидеть нелогичность картинки — если ей верить, то у всех браузеров с появлением новых версий производительность падает. Иногда так бывает, но так не может быть для всех браузеров.
0
Лимит про 100000 для
new Array(n)
стал для V8 неактуальным после codereview.chromium.org/397593008, теперь преаллокация быстрее, потому что преалоцированный массив остается быстрым. До этой правки он превращался в словарь. 0
Между статьёй и вами разница в 15 мажорных версий браузера и более 2 лет времени. Теперь и прототипы быстрее модулей под любым соусом, и предзаполненные массивы на полтора порядка быстрее.
0
«Не удаляйте элементы массивов» — а если это необходимо?
Нельзя чтоб образовывался 'пробел' в массиве, окей это понятно, но как поступить лучше? Перестроить массив через лодашевский _.without — нормальный вариант?
«Избегайте использования delete при удалении элементов объекта» — опять же, вот нужно мне по логике удалить элемент из объекта, как лучше поступить?
Нельзя чтоб образовывался 'пробел' в массиве, окей это понятно, но как поступить лучше? Перестроить массив через лодашевский _.without — нормальный вариант?
«Избегайте использования delete при удалении элементов объекта» — опять же, вот нужно мне по логике удалить элемент из объекта, как лучше поступить?
+1
НЛО прилетело и опубликовало эту надпись здесь
Рекомендации про удаление относится к использованию оператора
Если у вас есть объект, который вы используете как словарь (а не как объект), то кроме удаления
Если же у вас именно объект — то лучше просто сделать
С массивом точно также — если массив уже разреженный с кучей дырок, т.е. словарь по сути дела — то пользуйтесь
Все эти рекомендации не следует применять в слепую — надо просто понимать потенциальные проблемы, профилировать и решать уже после профилировки как разбираться с hotspotами.
delete
. Если у вас есть объект, который вы используете как словарь (а не как объект), то кроме удаления
delete
ом ничего не сделаешь.Если же у вас именно объект — то лучше просто сделать
o.p = null
. С массивом точно также — если массив уже разреженный с кучей дырок, т.е. словарь по сути дела — то пользуйтесь
delete
, в противном случае либо a[i] = null
или двигайте элементы вниз (тем же splice или руками)Все эти рекомендации не следует применять в слепую — надо просто понимать потенциальные проблемы, профилировать и решать уже после профилировки как разбираться с hotspotами.
0
Небольшой оффтоп, недавно наткнулся на такой странный код:
Если не ошибаюсь, этот код — оптимизация для v8, обусловленная разницей внутреннего представления объектов-словарей и объектов-структур. Можете прокомментировать его и актуально ли подобное сейчас?
function toFastProperties(obj) {
function f() {}
f.prototype = obj;
return f;
eval(obj);
}
Если не ошибаюсь, этот код — оптимизация для v8, обусловленная разницей внутреннего представления объектов-словарей и объектов-структур. Можете прокомментировать его и актуально ли подобное сейчас?
0
Это хак связанный с тем, что V8 старается держать прототипы объектов в fast mode. Получается, когда вы присваиваете медленный объект (dictionary/slow mode) в
Сей хак актуален, если вы знаете, что у вас есть объект находящийся по какой-то причине в словарном режиме и вам хочется его превратить в быстрый объект.
f.prototype
он превращается в быстрый. Сей хак актуален, если вы знаете, что у вас есть объект находящийся по какой-то причине в словарном режиме и вам хочется его превратить в быстрый объект.
+1
a[i] = null в данном случае разве не сделает массив массивом смешанных типов? То есть какого-то однозначно рекомендуемого метода нет, и надо выбирать компромиссное решение в зависимости от ситуации?
0
Разумеется если массив у нас изначально состоит из чисел (для других случаев тип элементов не отслеживается), то
null
действительно переведёт его просто в массив «чего угодно»), в этом случае a[i] = null
не подходит. Надо либо сдвигать элементы, либо писать специальный маркер в несуществующие позиции (например, a[i] = 0
). Конкретный подход зависит от назначения конкретного массива и причин, по которым нужно из него удалять элементы.+1
А точно в Backbone есть dispose? Потому что в свежей версии такой функции нет.
Большая проблема со статьями такого рода — они все уже давно устарели. Конкретно в этой статье предлагается набор советов от 2012 года. Уже 3 года прошло, большинство из этих советов — неактуальны.
Предлагаю автору добавить вверху дату оригинальной статьи, иначе на текущий момент многие из советов можно отнести к разряду «вредных».
Большая проблема со статьями такого рода — они все уже давно устарели. Конкретно в этой статье предлагается набор советов от 2012 года. Уже 3 года прошло, большинство из этих советов — неактуальны.
Предлагаю автору добавить вверху дату оригинальной статьи, иначе на текущий момент многие из советов можно отнести к разряду «вредных».
+6
AFAIK в Backbone никогда не было функции/метода с таким именем. Возможно это опечатка. Не знаю, что там имел в виду Эдди, но по смыслу там подходит stopListening.
0
В примере с генераций таблицы и добавления евентов есть косяк кажется. Переменная frag2 должна пересоздаваться внутри цикла for потому что сейчас каждая следующая строка таблицы будет содержать все td из предыдущих рядов.
0
Статья хорошая, но хотелось бы побольше услышать про оптимизацию именно при работе с DOM, т.к. какой бы быстрой не была функция и какой бы эффективной не была сборка мусора и распределение памяти — всё это сходит на нет, если мы собираемся много работать с DOM. В тексте статьи по этому поводу сказано фактически лишь одно — не работайте с DOM в цикле, для этого надо использовать documentFragment. Но что, если сам по себе documentFragment является очень большим, например, таблица 1000 строк по 5 колонок? У меня встраивание такого фрагмента вызывало небольшие подвисания браузера (приблизительно 0.5 с), какие бы рекомендации вы могли дать?
0
НЛО прилетело и опубликовало эту надпись здесь
Я всегда думал, что браузер делает пересчет уже на следующем «тике», когда текущий фрагмент js-кода «отпустил» однопоточный интерпретатор и управление вернулось назад в ядро js. Т.е. вставите вы в DOM 1 элемент или 100 — все равно пересчет будет выполнен 1 раз, когда произойдет выход из всех запущенных вложенных функций. Я так думал. Но это, похоже, неверно в силу замечаний про DocumentFragment? Поясните, пожалуйста.
Даже метод такой был: выполнять какие-то вещи на setTimeout(..., 1), т.е. на следующем событийном цикле, когда браузер пересчитал ширины-высоты.
Даже метод такой был: выполнять какие-то вещи на setTimeout(..., 1), т.е. на следующем событийном цикле, когда браузер пересчитал ширины-высоты.
+1
советую почитать про дерево перерисовки и работу селекторов, чтобы понимать про DOM лучше. Можно также соответствующую главку из книжки
speedupyourwebsite.ru/books/reactive-websites/
speedupyourwebsite.ru/books/reactive-websites/
0
Есть и непонимание по поводу того, как работает null. Установка ссылки на объект в null не обнуляет объект. ПисатьПереведённый автор здесь противоречит сам себе: мысль, изложенная до фрагмента кода, фактически противоречит мысли, изложенной после него.o.x = null лучше, чем использовать delete, но смысла это не имеет.
var o = { x: 1 }; o = null; o; // null o.x // TypeError
Если эта ссылка была последней ссылкой на объект, его затем приберёт сборщик мусора. Если это была не последняя ссылка, до него можно добраться, и сборщик его не подберёт.
Верно написано, что переменная является всего лишь ссылкою на объект. Но именно поэтому её и зануляют (обращают в null), чтобы не оставалось лишних ссылок на объект и начал работать сборщик мусора, подчистив объект. Если переменная является частью области видимости некоторого замыкания, то ссылка на объект может жить очень долго, если её не занулить — именно так и возникают «утечки памяти».
+4
Если кратко:
1. Не используйте переменные.
2. Если очень надо их использовать, хотя бы не записывайте в них значения и нигде не используйте.
1. Не используйте переменные.
2. Если очень надо их использовать, хотя бы не записывайте в них значения и нигде не используйте.
-1
При создании таблицы, мне кажется лишним добавление ячеек во фрагмент, почему их сразу не добавлять в элемент строки, ведь элемент строки находится во фрагменте и добавление ячеек в строки не вызовет перерисовки. Так что
frag2.appendChild(td);
мне кажется лишними телодвижениями.+1
«простить исправить» — красиво звучит :-)
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Пишем быстрый и экономный код на JavaScript