Pull to refresh

Comments 17

«Сорт элемента» — очень неудачный перевод, как мне кажется. Есть устоявшееся понятие «тип элемента»

К сожалению, понятие "тип" (type) для JavaScript уже используется в другом значении. К примеру:


const arr = [1, 2, 3];

Тип (type) элементов — number; сорт элементов (elements kind) — PACKED_SMI_ELEMENTS.

Тогда «содержимое». Не знаю почему, но мне очень режет глаз такой перевод.

Слоупок на связи и соощает, что наличие типов в самом языке js никак не резервирует этот термин в рантайме. В языке могут быть свои типы, в реализации v8 внутри свои типы и ничто не мешает их так называть. Сорта элементов для заголовка норм, отсылка на мем, но как термин сильно режит ухо.

А почему преобразование в реальный Array сделано через Array.prototype.slice, а не через стандартный Array.from?

Этот вопрос нужно задать автору оригинала. Я бы, действительно, использовал Array.from.


Мое предположение в том, что статью начали писать до того, как стали широко доступны возможности ES 2015.

Кто-нибудь вникал как оно устроено под капотом? Было бы интересно узнать в каких случаях 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. Наверное это классические цельно-блочные массивы с адресной арифметикой.

Нашёл


TNode<IntPtrT> CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
                                                         ElementsKind kind,
                                                         ParameterMode mode,
                                                         int base_size) {
  // ...

  if (constant_index) {
    return IntPtrConstant(base_size + element_size * index);
  }

Кажется это оно.

Вместо arguments следует использовать rest parameters, доступные, начиная с ECMAScript 2015. Они являются настоящими массивами, и к тому же выглядят более читаемо.

Только не забудьте скормить это бейбел и преобразовать автоматически обратно в работу с arguments.


Вообще статья интересная, но проблема в том, что в js мало того что часто нужно поддерживать старые браузеры все ещё, так и оптимизации не стабильны — выход новой версии движка может как и смягчить правила, так и ужесточить. Как было с исключениями — сперва они ломали JIT, теперь не ломают, так и тут выход за пределы может перестать быть условием превращения массива в более медленный

Я считаю, что не все так плохо.


Только не забудьте скормить это бейбел и преобразовать автоматически обратно в работу с arguments.

caniuse говорит, что ES6 (он же ES2015), где ввели rest parameters, есть у порядка 95% пользователей. Мне кажется, что для большинства вебсайтов как раз этот стандарт логично брать как минимальный поддерживаемый.


в js мало того что часто нужно поддерживать старые браузеры все ещё

Есть как минимум два случая, когда это не так: Node.js и Electron. В случае разработки под эти платформы нам точно известен движок и его (минимальная) версия, и можно сознательно рассчитывать на оптимизации.

Так то оно так, но мы долго выбивали себе отказ от старых IE (потому что продажникам конечно удобнее написать что работает хоть в нетскейп). Вообще помогает делать две сборки — под старые и новые браузеры, задача решаемая, но много ли людей ее решают?


Про Электрон согласен, но сложно представить числодробилку на nodejs, а массивы из трёх элементов (которые обычно вообще по объектам, а не числам) оптимизировать — экономить на спичках. Справедливости ради, не ходить за пределы массива и использовать ...rest вместо аргументов — хорошие практики сами по себе, но разряженность массивов — последнее, чтобы я советовал оптимизировать.


К слову, если уж на то пошло, часто стоит задуматься об использовании Set вместо массива если вы хотите проверить находится ли свойство в перечне.

Ну т.е. я помню времена когда спорили что одинарные кавычки работают быстрее двойных и все как бешеные исправляли это. А на практике прирост нулевой. Так и тут — я уже вижу как впечатлительные коллеги будут комментировать что у меня разряженный массив (хм, вообще очень редкая ситуация если так подумать), а сами будут использовать reduce, пересоздавая массив на каждом элементе. Зато неразряженный!

Справедливости ради, автор явно отмечает, что в большинстве случаев не стоит таким заморачиваться. А именно про разреженные массивы даже отдельно говорит, что прирост, чаще всего, будет незаметен.


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

спорили что одинарные кавычки работают быстрее двойных и все как бешеные исправляли это.

А расскажите подробнее, пожалуйста? Я этих времен не застал, и теперь очень интересно. Это действительно было правдой?

Это из PHP, там в двойных кавычках текст интерпретируется, в одинарных нет. Звучит логично, что двойные должны быть медленннее, но на практике это было экономией на спичках. Не уверен как дела сейчас обстоят.

Sign up to leave a comment.

Articles