четверг, 6 июня 2019 г.

V8 internals - хранение объектов и массивов. Инициализация глобального контекста

       Итак, я продолжаю свои упражнения в археологии. Для начала меня заинтересовал вопрос - вот есть у меня виртуальная машина, а как в ней появляются все эти прекрасные "встроенные функции" ? Собственно в этой статье это довольно подробно объясняется - https://v8.dev/blog/custom-startup-snapshots  Если в кратце то  в папочке tools есть утилита js2c.py которая конвертирует javascript код из папочки lib в бинарный массив который можно напрямую загрузить в V8 Heap.  Таким образом инициализация контекста (объект global) очень сильно ускоряется.
        Что касается хранения объектов в памяти V8 (memory layout) - по этой теме есть много статей, и даже доклад от Fedor Indutnyhttps://www.youtube.com/watch?v=tLyIs_0cUyc но на этот раз меня его доклад не впечатлил. Он прошелся по верхушкам и прорекламировал llnode - node.js плагин для lldb. Большое спасибо Федору за инструмент, но тема memory layout в его докладе была раскрыта на 10% не больше. Лучше всего это объяснено в этой статье - https://v8.dev/blog/fast-properties В ней акцент сделан на хранении свойств, а в следующей статье https://v8.dev/blog/elements-kinds более подробно объяснено хранение элементов массива.   Вообще в статьях очень много полезной информации по оптимизации - как писать код так чтобы V8 его быстрее исполнял. Ведь благодаря создателям JavaScript - одну и ту же вещь там можно написать 20 способами. Вообще мне кажется что люди проектировавшие JavaScript изначально - прямо-таки ненавидили разработчиков компиляторов/интерпретаторов и сделали все чтобы затруднить разработку компиляторов/интерпретаторов для JavaScript. 
В общем обе статьи я бы рекомендовал прочитать каждому JS разработчику стремящемуся писать оптимальный код. Для тех кто не в ладах с английским языком перескажу в кратце:
  • Если вы хотите чтобы доступ к свойствам объекта происходил быстро - явно определяйте все его свойства при создании объекта. Определяйте их в одном и том же порядке(в конструкторе). Не добавляйте новые свойства по ходу использования объекта. Не используйте Object.defineProperty() если у вас нет для этого большой необходимости. 
  • Избегайте полиморфизма. То есть передайвайте в функцию только аргументы одного типа. 
  • Не храните элементы разных типов в одном массиве. Явно приводите их к одному виду.
  • Избегайте разряженных массивов (массивов с пропусками). Сплошные массивы работают намного быстрее
  • Не пытайтесь обращаться к несуществующим элементам массива (требует обращения к prototype)

Комментариев нет:

Отправить комментарий