As For JS
3.43K subscribers
130 photos
12 videos
4 files
375 links
As For JavaScript...
Обсуждения — @AsForJsTalks
Download Telegram
Live stream scheduled for
Готовность 5 минут...
Live stream started
Live stream finished (2 hours)
Позднее может выложим видео или будем выкладывать в YouTube.

Думаю там будет удобнее.

Просто пока у нас пробные попытки, но это уже, наверное, 5 пробная попытка)
As For JS
As For JS – Новая попытка.
Аудио, это отдельная часть. —
Начало общения.
Потом включили запись видеотрансляции.
👍5
Аудиозапись видеотрансляции.
Может кому будет так удобнее.
As For JavaScript Coalesce Expression - Nullish coalescing operator - ??

Abstract
О том, почему coalesce expression является идиотизмом притянутым в спецификацию идиотами не понимающими архитектуру языка, а так же о том как разработчики V8 реализовали эту парашу именно как парашу.


Что это такое ваше за Coalesce Expression - я забыл - напомни мне - я упырь
не волноваться, я тоже упырь и совершенно не понимаю как придумывают эти названия.
Потому вот документация и примеры:
Официальная спецификация ECMA
MDN
пример:
var theThing;
(theThing ?? "Yo");
// Если theThing связан с undefined или null результат вычисления выражения будет "Yo
"


В чем проблема проверять и на null и на undefined одной конструкцией
undefined - это primitive value которое устанавливается для идентификаторов созданных при помощи variable statement.
null
- это primitive value которое связывают с идентификатором который в прошлом или в будущем был/будет связан с обьектом, но в его текущем состоянии обьект не определен. То есть null - это обьект с нулевой структурой. Не путать с указателями из других языков.

Эта разница принципиальна для runtime. На основе этой информации RunTime может предпринимать совершенно разные шаги каким образом можно работать с нашим кодом. Очевидно, что идентификатор связанный с undefined - это идентификатор поведение которого в будущем предсказать невозможно. Идентификатор связанный с null - в будущем будет обьектом или ранее использовался как обьект.

По этой причине, Coalesce expression бесполезно так как включает в себя два пограничных случая, которые не пересекаются. Иными словами, если в Вашей программе Вы вынуждены проверять идентификатор на то может ли он быть связан в одной и той же ситуации с null или undefined - то у Вас проблемы с вашим кодом, его архитектурой. Так как если Вы знаете что Ваш идентификатор будет связан с обьектом в будущем - он обязан быть про инициализирован как null, а не undefined.

Конечно если в Ваши задачи входит писать эффективный код. То есть код, который претендует на максимальную производительность.

Посмотрите на официальные API - если API должно вернуть обьект, но при этом что-то произошло, что не позволяет это сделать, то API всегда вернет null. Чем прямо сообщает RunTime - да я должен был вернуть обьект, но что-то пошло не так.


Байт код от V8 для Coalesce expression
Именно ради этого раздела я и затеял все это словоблудие.

JavaScript код:
var theThing;
(theThing ?? "Yo");

byteCode V8:
    Ldar r0
/* Регистр r0 это наш идентификатор theThing.
Ldar - это загрузка содержимого регистра в регистр аккумулятора.
Регистр аккумулятора - это особенный уникальный регистр,
который существует в единственном числе в V8. Через него делаются практически все операции.
*/

    JumpIfUndefinedOrNull "label1"
/* Это непосредственно операция ??,
на языке байткода V8 звучит как - если в регистре аккумулятора находится что-то
что является undefined или null то сделать переход к метке label1
*/

    Jump "label2"    
// безусловный переход к метке label2

label1:              
// метка label1 к которой происходит переход

    LdaConstant [0]  
// загрузить в аккумулятор подготовленную константу. В нашем случае это будет ссылка на "Yo"

label2:              
// метка label2 к которой происходит переход
 
// Other code

Этот же код без комментариев:
    Ldar r0 
JumpIfUndefinedOrNull "label1"
Jump "label2"
label1:
LdaConstant [0]
label2:


Ничего не покоробило в логике этого кода?
🔥3
Для того, чтобы наглядно показать о чем я говорю, я приведу еще один код, на этот раз для JavaScript кода, где вместо ?? будем использовать &&:
var theThing;
(theThing && "Yo");

а теперь тот же код в byteCode V8:
Ldar r0
JumpIfToBooleanFalse "label1"
// Это непосредственно операция &&
LdaConstant [0]
label1:


Теперь видна разница между реализацией ?? и &&?
Совершенно верно - в реализации для ?? (Coalesce) используется два перехода ( JumpIfUndefinedOrNull и Jump "label2") , в отличии от && где использован только один переход.

Что естественно отражается на производительности: && или || в среднем на 7% выполняется быстрее для кода, который не был оптимизирован TurboFan. В оптимизированном случае разницы нет.

Напомню, что в текущих условиях, получить оптимизацию от turboFan вам нужно повторить выполнения одного и того же кода не менее 1200 раз, а в некоторых случаях гораздо больше. То есть в современных реализиях, большая часть нашего кода не оптимизируется вообще. В следствии чего те самые 7% уже не кажутся такими несущественными.


А как правильно
Правильно и наиболее эффективно, в случае V8 использовать максимально специфичные конструкции для ситуаций когда нам нужно что-то делать с логикой в зависимости от null или undefined

Например, для ситуации когда мы хотим проверить произошла ли инициализация идентификатора или он все еще undefined:
var theThing;
theThing === undefined && "Yo";

Да, синтаксис содержит слишком много букаф. Но посмотрите какой вкусный код генерирует для этого V8:
Ldar r0
TestUndefined
JumpIfFalse "label1"

LdaConstant [0]
label1:

V8 в своем bytcode имеет особую инструкцию проверки именно на undefined - TestUndefined и соответственно мы видим только один переход.

Аналогичная история с null
var theThing;
theThing === null && "Yo";

V8 код:
Ldar r0
TestNull
JumpIfFalse "label1"

LdaConstant [0]
label1:


Или так:
vat theThing;
theThing ||= 1;
// но следует четко отдавать себе отчет в том, с чем именно связано это условие


Вместо ИГОГО:
Всегда следует помнить о том, сколько стоят подобные оптимизации. Всегда следует отдавать отчет себе в том, что слова: вот || на 7% быстрее чем ?? говорит именно о 7% выигрыше в затратах на реализацию именно этих конструкций, которые на фоне прочих проблем программы могут оказаться ничтожными. То есть настолько бесполезными, что не будет существенной разницы - хорошую вы выбрали конструкцию или плохую, но фоне прочих проблем кода, выигрыш не будет ощутим.
🔥5💯2👍1
Обьявление:
В комментариях к этому сообщению, можно задать вопрос - а что будет быстрее это или это?
Например: Что быстрее var let или const?

Или
А как влияет на производительность создание идентификаторов? Если я создаю сотни промежуточных идентификаторов - это плохо или ничего страшного?

Или
любой другой вопрос относящийся к JavaScript или смежным темам.

Я прочитаю вопрос и если смогу на него ответить - то обязательно дам развернутый ответ.

Мне это нужно для того, чтобы нагружать голову, поскольку я сейчас очень много лежу и у меня появилось много времени для того, чтобы что-то обдумать. А без темы, я скатываюсь в сторону текущих проблем о которых пока думать бессмысленно.
👍2👀1
Оголошення.

Друзі, якщо я можу щось для Вас зробити саме Українською, у площині вивчення JavaScript, або у суміжних темах - напишіть мені будь ласка у коментарі до цього повідомлення - що саме.

Я обов'язково насамперед зроблю саме це.
Слава Україні.
7🤡2
Гдето через два часа, будет стрим на ютубе на тему проблем gpt чата и генерации js кода.

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

а если не успею - то просто сюда кину текстом.
9
Друзья, приглашаем вас на стрим, который пройдёт здесь в 21:30 по Киеву (21:30 по Москве).

Тема:
"О целесообразности использования числовых (number) ключей при работе с JavaScript объектами. "

#онлайн_встреча
@AsForJavaScript
6👍3
Live stream scheduled for
Live stream started