Обновить
10
0
Yuri Karadzhov@Large

Пользователь

Отправить сообщение
Однако там есть ещё более забавная вещь: автоматическое приведение типов. Каждый раз, когда мы пытаемся использовать простое значение как объект (скажем, получить доступ к его свойству), оно «оборачивается» в соответствующую объектную обёртку.
Это не приведение типов, это боксинг/анбоксинг, приведение типов это когда мы хотим объек со строкой или строку с числом сложить.

(2 * 2 == 5).ifThenElse(
    //надеюсь, в 2017 году стрелочные функции уже никого не смущают
    () => alert("Freedom is Slavery"),
    () => alert("O brave new world!")
)
А зачем это так реализовывать если есть достаточно много красивых функциональных библиотек для js? Разница будет только в том, что вы монаду объявите явно
If(2 * 2 === 5).fold(
    () => alert("O brave new world!"),
    () => alert("Freedom is Slavery")
);
Поэтому сейчас для визуализации в вебе часто используется библиотека для языка JavaScript — WebGL, которая позволяет создавать интерактивную 3D-графику. Однако, из-за недостатков языка, таких как отсутствие многопоточности, библиотека не может полноценно удовлетворить потребности игроделов. Ей на смену консорциумом W3C (куда входят: Microsoft, Google, Mozilla и др.) разрабатывается новый низкоуровневый бинарный компилируемый формат WebAssembly.


WebGL — это не библиотека для языка JavaScript, а Web API, wasm будет работать с тем же API, и проблема тут не в многопоточности которая в принципе реализуема через web workers, а в более предсказуемой модели работы с памятью и ускорения за счет типизации, опять же гораздо проще разрабатывать кроссплатформеные игры.
Можно прямо при вычислениях обнулять mem[n — 3] при n > 2 и тогда не будет выделяться столько памяти, можно то же самое и для объекта сделать. Массив все равно будет быстрее, но пример плохой, мои примеры с векторами и конструкторами видеть не хотят, в кодпен они не влезут так как там полноценное приложение, а не парочка тестов, но если начать реализовывать, то видно во что превращается код даже на синтетическом тестировании.
Не знаю, что там по поводу соседней ветки и примера из нее, но если вы в приведенном коде память выделите сразу, то получите ускорение х2 для массива и по сравнению с хешем это х3.5 и никаких глобальных кешей. Пример опять таки не показательный, так как вы создаете всего один array-like object, для тестирования этого случая нужно сравнивать конструктор и конструктор с динамически добавляемым свойством и создавать тысячи объектов, мерять нужно только то, что вы меряете и ничего лишнего, но даже приведенный код дает понять, что разница есть и она ощутима.
https://www.youtube.com/watch?v=z0MXK7bzXuU
Насколько я знаю — нет, компилятор сначала решит, что вы не сволочь и хотели именно массив целых чисел, если вы в него запишите дробное, он скажет, ок, наверное это массив дробных чисел, я ошибся, с кем не бывает, пересоздаст его и перенесет значения туда, а если вы потом туда запишете строку, то он проклянет вас и уже тогда создаст список.
Разница между типизированными и не типизированными не значительна пока мы остаемся в рамках одного типа. Для временных объектов нетипизированные оказываются даже быстрее.
Надежда умирает последней, у меня кстати весьма симпатичная реализация на авл деревьях, мне больно называть ее кривым велосипедом =) Вообще Map и Set очень ограничены, вы не сможете итерировать в обратном порядке или начиная с какого-то объекта, так что никуда от своих реализаций мы не денемся.
Это не про убийц оптимизации, а про плохие алгоритмы

Убийцы оптимизации это участки кода, которые приводят компилятор в ступор. Мой первый комментарий с которым вы продолжаете спорить как раз вам говорил о том, что даже если ваш код оптимизируется без знания работы вм он не обязательно будет быстрым, более того, если вы пишите UI то турбофан с большой вероятностью и не дойдет до вашего кода и он будет просто переведен в байт код и выполнен игнишн без всяких оптимизаций и это вам эти синтетические тесты вообще даром не нужны. Если же вы пишите игры, то эти синтетические тесты вам тоже даром не нужны, но вам нужно понимать как вм работает с памятью, потому что
const a = new Array(size); for(...) a[i] = ...; и const a = []; for(...) a.push(...); это две большие разницы и алгоритмы тут вообще не при чем. Так же ни при чем алгоритмы и к созданию временных переменных скажем с помощью Array.prototype.slice или к дополнительным вызовам в Array.prototype.reduce, просто одни языковые конструкции эффективнее других, хотя и те и другие будут оптимизироваться компилятором.

По поводу вашего примера:
0. Вы меряете подсчет фибоначи, сумму и округление кроме всего прочего, но работаете всего с одним объектом, честнее было бы мерять результат работы нормального конструктора и конструктора с добавлением свойств и создавать тысячи объектов.
1. Для Set код вообще не правильный и вы по сути меряете производительность динамического объекта.
2. Вы и так видите, что массив быстрее, а теперь вынесите инициализацию за функцию и сразу выделите память new Array(it) метод станет быстрее еще в два раза вот так вот бесплатно и никаких алгоритмов тут нет.

Map и Set пока плохо оптимизируются компилятором и вряд ли будут, скорей всего их постигнет участь DataView, но не смотря на это их нужно использовать там где нужны динамические таблицы потому как это красиво и правильно, а вот если уже нужна производительность — заменять на собственные быстрые реализации на авл-деревьях или массивах, в зависимости от потребностей.

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

Я не хочу больше спорить на эту тему и предпочту общение с создателями ААА игр.
Чтоб что-то отдать webgl вам нужно написать минимум два шейдера на glsl, это не имеет ни какого отношения к 3д, webgl ничего о 3д не знает и не должен. webgl действительно работает с типизированными массивами и текстурами, в них можно хранить свои данные.
В асм нет объектов, так что будет часть кода на js для получения и работы с gl контекстом.

Если компилятор скомпилировал js код то он в принципе тоже перестает проверять типы и предполагает, что они какие-то конкретные пока не обнаруживается обратного. Основной выигрыш получается за счет отсутствия объектов и динамических свойств (кроме таблицы функций).

Ну сейчас можно выдать wasm с фолбеком на asmjs. Сыроват только из за поддержки браузерами. asmjs кажется забросили и это обидно, скажем поддержка i64 есть только в wasm.

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

С играми тоже не все однозначно, проще скомпилировать, но как правило менее производительно (компиляторы пока не настолько умны и некоторые места всегда будет проще писать руками, чем заставить компилятор понять что вы имели в виду) и пока не добавили кросс взаимодействие js — wasm вы получите минимум контроля над скомпилированым модулем, отлаживать который та еще радость.

Хорошо работает комбинация этих подходов — часть asmjs/wasm модулем, часть на gpu на glsl, остальное js.
Правильно, а не слепо проверять возможность компиляции какой-то части языка.
покажите код, давать результаты тестирования в абсолютных значениях и без кода нет смысла. динамически менять свойства объекта это моветон, а не удобство, программист ожидает одну форму объекта, а у вас приходит другая так как вы где-то динамически что-то поменяли.

Вы уже в который раз пишите мне, что я делаю и опять-таки ошибаетесь. Я пишу не сложным путем, я пишу максимально просто и потом вместо каких-то синтетических тестов на оптимизацию пользуюсь профайлером и уже в зависимости от его результатов делаю те или иные оптимизации основываясь на том как работает движок. Те или иные оптимизации не означает написать for(var i = 0, l = arr.length; i < l; i++) {...}, это означат уменьшить выделение памяти, оптимизировать работу путем линейного выделения памяти, уменьшить количество вызовов и т.д. В некоторых конкретных случаях, приходится делать микрооптимизации, чтоб вывести конкретный движек из ступора, но тут опять же нужен профайлер так как обычно все равно компилируется какая-то часть программы или нет, важно насколько она критична и как быстро работает и ускорение вам нужно сегодня, а не через пару версий так как релиз сегодня.

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

Не похоже, что вы занимались вычислениями или 3д играми.
Именно так, и я проверила как это влияет на производительность, вместо 140мс, код выполнился за 180мс, добавляла 20 свойств динамически

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

Нет

С вашим нет я не соглашусь. Для UI нет, для игр и вычислений — да. Каждому свое.
По сути я ответил чуть выше. В вопросах производительности js очень сложный язык. На самом деле попробуйте задачку с векторами, красиво, умеренно быстро и без повторений не получится.

Я вам как раз и говорю, что изучать оптимизации не нужно, эвристики для vm меняются часто, но вот принципы работы остаются на долго. Оптимизировать нужно лишь тогда когда это действительно нужно и тут важно иметь тесты производительности ибо какие-то факты о хаках в v8 вряд ли помогут вам с другими браузерами. Уже разводили эту дискуссию в статье об убийцах оптимизации и я как раз и говорил, что все устаревает и все нужно тестировать =)
Кстати

1. Не переназначать переменные другим типом

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

Долгое время у const и let были проблемы с производительностью на v8 из за реализации TDZ.
3. Не добавлять динамически свойства в объект
3. потери производительности незначительны

Вот так как раз делать нельзя так как создаются новые скрытые классы для этих объектов и потери производительности значительны. Опять таки это как раз пример очень некрасивого кода, для хеш таблиц можно использовать встроенный Map или написать свою реализацию.

4. использовать for..of

Генераторы пока не оптимизируются, если вы пишете красивый код в функциональном стиле то for-of вам не поможет.

5. Большое количество конкатенаций мелких строк (например, посимвольно) ведет к перерасходу памяти
5. использовать arr.push вместо +=

Строки вообще дорогие в js, и этот совет палка о двух концах, сборщик мусора в принципе легко справится с короткоживущими строками, а вот arr.join может стоить гораздо дороже +=, тут нужно смотреть на конкретный случай. Но сразу arr.push дороже чем new Array(size) и arr[i] =…
Есть всего 3-5 простых некритичных правила, чтобы js-код не страдал потерей производительности

Все так, но не для всех задач этого достаточно. При написании парсеров или игровой логики прийдется думать о том как выделяется память и куда расходуются циклы процессора. Мегаморфизм может быть по типам Float32 vs Uint8 и прийдется писать две одинаковые функции для каждого из них.

Не нужно, vm это черный ящик, сегодня он так работает, завтра по другому

И тем не менее пока у нас нет встроенных типов вы никуда не денетесь от скрытых классов и память будет выделятся по прежним правилам. И это вам не нужно пока у вас нет таких задач, а как только появятся и Safari будет проигрывать Chrome по производительности в 100 раз, сразу прийдется думать что с ним не так и где компилятор ступил.

Раньше делали inline asm вставки в С код, сейчас чтобы сделать inline вставку, которая будет быстрее, чем clang заоптимизирует, настолько сложно, что этим мало кто занимается

Не делают так как сложно и дорого поддерживать целый зоопарк процессорных архитектур. И на самом деле делают, тот же v8 имеет асемблерные вставки под все архитектуры.

Вы предлагаете заниматься тем же для js, ускорять то, что не внесет даже 0.1% в итоговую производительность, а может даже замедлит

Нет, я этого не предлагаю. Я говорю, что даже красивый код без деоптимизации может работать чертовски медленно. Опять же я не призываю писать некрасивый код, просто оптимизировать нужно вовремя и это может дать очень существенный приток производительности в десятки и даже сотни раз. Кроме того есть еще asmjs и wasm, а так же вычисления на gpu, вставки которых так же помогают значительно ускорить критически важный код.

Наоборот, именно сейчас можно писать компактный, красивый, с async-await код, который будет быстрым, который удобно писать и понимать

До какого-то придела да, а потом вы решите, что функциональный код красивее императивного async-await или у вас появятся задачи где производительность критична и код резко испортится.

Вот пару примеров когда код будет далек от идеалов красоты:
0. DataView не инлайнится и его приходится переписывть через типизированные массивы
1. Попробуйте организовать классы Vec extends Array, Vec2, Vec3, Vec4 без дублирования и потери производительности. И тут уже как минимум прийдется возвращаться к Array.prototype.call(this.constructor.size) вместо extend, так как в super объект this не доступен. А по хорошему вообще нужно выделять кусок памяти и работать внутри него, чтоб не вскипятить процессор, и все что можно сбросить на gpu.
Ну о текущей версии как раз и речь, ни нода ни браузер не оптимизирует, но да в турбофан и игнишн сейчас начали вкладываться и видимо сделают наконец-то достойную виртуальную машину для js.

Может да, а может нет. Держать все нет смысла, так как оптимизатор развивается быстрее, чем мы пишем код

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

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность