Комментарии 17
«Сорт элемента» — очень неудачный перевод, как мне кажется. Есть устоявшееся понятие «тип элемента»
К сожалению, понятие "тип" (type) для JavaScript уже используется в другом значении. К примеру:
const arr = [1, 2, 3];
Тип (type) элементов — number
; сорт элементов (elements kind) — PACKED_SMI_ELEMENTS
.
Тогда «содержимое». Не знаю почему, но мне очень режет глаз такой перевод.
Слоупок на связи и соощает, что наличие типов в самом языке js никак не резервирует этот термин в рантайме. В языке могут быть свои типы, в реализации v8 внутри свои типы и ничто не мешает их так называть. Сорта элементов для заголовка норм, отсылка на мем, но как термин сильно режит ухо.
А почему преобразование в реальный Array сделано через Array.prototype.slice
, а не через стандартный Array.from
?
Кто-нибудь вникал как оно устроено под капотом? Было бы интересно узнать в каких случаях v8 использует адрессную арифметику вида:
const arr = [0,1,2,3,4];
arr[3]; // &arr + sizeof(arr[0]) * 3
Полагаю для holed это невозможно. Но используется ли это в случае packed? Хранится ли это всё в одном последовательном блоке памяти или оно дробится на chunk-и? По сути насколько эти elements близки к нормальным массивов из языков со статической системой типов.
Про это можно почитать подробнее, например, в этой статье (кажется, мне стоило сначала перевести ее, а не эту :)
Если совсем коротко: есть два основных способа хранения: fast (массив) и slow (словарь). Packed элементы всегда хранятся в массиве, для holey-элементов есть два варианта: массив со специальным значением для "дырки" или словарь.
Спасибо за ссылку. Я эту статью даже пару лет назад читал вроде.
Fast elements are simple VM-internal arrays where the property index maps to the index in the elements store
По сути это всё что я там нашёл про это. Т.е. всё упирается в то, что такое VM-internal arrays и как они map-ят индексы к the elements store. Наверное это классические цельно-блочные массивы с адресной арифметикой.
Вместо arguments следует использовать rest parameters, доступные, начиная с ECMAScript 2015. Они являются настоящими массивами, и к тому же выглядят более читаемо.
Только не забудьте скормить это бейбел и преобразовать автоматически обратно в работу с arguments.
Вообще статья интересная, но проблема в том, что в js мало того что часто нужно поддерживать старые браузеры все ещё, так и оптимизации не стабильны — выход новой версии движка может как и смягчить правила, так и ужесточить. Как было с исключениями — сперва они ломали JIT, теперь не ломают, так и тут выход за пределы может перестать быть условием превращения массива в более медленный
Я считаю, что не все так плохо.
Только не забудьте скормить это бейбел и преобразовать автоматически обратно в работу с arguments.
caniuse говорит, что ES6 (он же ES2015), где ввели rest parameters, есть у порядка 95% пользователей. Мне кажется, что для большинства вебсайтов как раз этот стандарт логично брать как минимальный поддерживаемый.
в js мало того что часто нужно поддерживать старые браузеры все ещё
Есть как минимум два случая, когда это не так: Node.js и Electron. В случае разработки под эти платформы нам точно известен движок и его (минимальная) версия, и можно сознательно рассчитывать на оптимизации.
Так то оно так, но мы долго выбивали себе отказ от старых IE (потому что продажникам конечно удобнее написать что работает хоть в нетскейп). Вообще помогает делать две сборки — под старые и новые браузеры, задача решаемая, но много ли людей ее решают?
Про Электрон согласен, но сложно представить числодробилку на nodejs, а массивы из трёх элементов (которые обычно вообще по объектам, а не числам) оптимизировать — экономить на спичках. Справедливости ради, не ходить за пределы массива и использовать ...rest вместо аргументов — хорошие практики сами по себе, но разряженность массивов — последнее, чтобы я советовал оптимизировать.
К слову, если уж на то пошло, часто стоит задуматься об использовании Set вместо массива если вы хотите проверить находится ли свойство в перечне.
Ну т.е. я помню времена когда спорили что одинарные кавычки работают быстрее двойных и все как бешеные исправляли это. А на практике прирост нулевой. Так и тут — я уже вижу как впечатлительные коллеги будут комментировать что у меня разряженный массив (хм, вообще очень редкая ситуация если так подумать), а сами будут использовать reduce, пересоздавая массив на каждом элементе. Зато неразряженный!
Справедливости ради, автор явно отмечает, что в большинстве случаев не стоит таким заморачиваться. А именно про разреженные массивы даже отдельно говорит, что прирост, чаще всего, будет незаметен.
Карго-культ из таких советов делать, разумеется, не стоит. Но они помогают лучше понять, почему какой-то код может быть медленнее, чем другой.
спорили что одинарные кавычки работают быстрее двойных и все как бешеные исправляли это.
А расскажите подробнее, пожалуйста? Я этих времен не застал, и теперь очень интересно. Это действительно было правдой?
Сорта элементов (element kinds) в движке V8