Comments 34
Респектище, классное исследование! Ну и на JS еще все нормально, раз он пускает разработчика в многопоточность и разделяемую память. Возился со схожей задачей в Dart, и там ты просто повязан по рукам и ногам ограничениями архитектуры языка, и в итоге по факту остается только колупаться в одном потоке...
А Изоляты чем в дарте не устроили?
Ну а где же там разделяемая память? А возможность из изолята добраться до канваса в Дарте вообще звучит как магия - доступ к графическим ресурсам сделат только из основного изолята, всем остальным дозволено только циферки считать и копированием пересылать в основной....
Скорее всего потому что графические ресурсы находятся в GPU и из RAM без копирования не обойтись.
В js доступ к графическим ресурсам из воркеров есть в хроме через OffscreenCanvas и он недавно только релизнут на ios17. Молодая технология, чтобы завидовать js. (и не факт, что это нужно, если вы не 3D игру портируете)
В дарте общую память обсуждают тут, и просят примеры использования.
https://github.com/dart-lang/language/issues/333#issuecomment-2045274873
Аналогично автору, который не знал, что для разделяемой воркерами памяти необходимо браузеру прислать заголовки, много ли подобных задач, которые потребовали бы ее?
Дарт не планировался как игровой движок. Как и js. В последнем только для васма есть потребность в общей памяти.
Можете использовать FFI и не ограничивать себя дартом, правда придется под каждую платформу собирать бинарник...
Ну да, в том и парадокс, что вроде как "молодая технология, отчасти призванная обойти недостатки старой", а по факту получается, что старая-то во многих кейсах её обходит, и, вероятно, ещё многие годы будет обходить.
А если сравнивать с TS то Dart это изначально мертворожденный язык, который хуже чем то что уже есть.
Я вообще пишу на классическом стеке: пыха и js. Ну, бОльшую часть профессиональной жизни. А тут вот выбрал для интереса какой-нибудь язык из списка "восходящих звёзд". Бесконечно можно читать обзоры про плюсы и минусы, но лучший способ - это самому погрузиться. Вот я и погрузился)) не могу отделаться от ощущения, что теперь, вот, обтекаю. Хотя есть там и плюсы, но о них все и так пишут.
Разве каждое ядро не имеет свой собственный кэш L1? Разве магическая eventual visibility не мешает потокам писать данные?
А как пример того что некоторая осторожность позволяет не убиться отправляясь в темноту с Гуглом и ChatGOT но без желания темноту освещать - очень интересно. И как пример отношения к математическим конструкциям как к физическим - тоже интересно.
попробуйте запустить реальную версию, просто выполнив bun http.ts в терминале
Стоило бы отметить, что для этого нужно зарегистрироваться на CodeSandbox и форкнуть проект. Иначе просто нет доступа к терминалу.
Не получилось запуститься даже авторизовавшись и форкнув...
во фрейме почему-то оно у меня не рендерило, я открывал получившийся урл в новой вкладке
Начнем с того, что я не понял, что надо написать и что открыть. bum run, bum build не работают.
UPD: а, "bun run http.ts"
bun http.ts
Это запустит http-сервер, который будет доступен через выделенный сервисом урл.
Для чего тут такие сложности с CodeSandbox? Разве это не обычный скрипт, который из статичного файла можно запустить? Полезу сам посмотрю.
А так вот же у автора есть ссылка на просто скрипт, который сразу работает.
https://dgerrells.com/sabby?count=20000000
Чтобы можно было отдать браузеру заголовки, без которых он не предоставит скрипту SharedArrayBuffer. В статье об этом тоже написано. А в остальном это обычная статика.
Мне удалось дос Мне удалось достичь результата в 1 миллион частиц на телефонном CPU при частоте 60 FPS. Приличный результат, учитывая что всё это Javascript, но он не особо впечатляет. Уверен, что компилируемый язык был бы в десять раз быстрее, а если допустить, что он может использовать команды SIMD в коротких циклах, то скорость будет ещё выше.
Слабые места остались canvas и js, можно было бы использовать web assembly, для вычислений и webgl для рендеринга, либо полностью перейти в webgl, может и получили бы эти +10х
Суть была не в частицах, а в поиске осязаемых горизонтов производительности js на цпу.
Вы заблуждаетесь.
1) web assembly не может быть быстрее js кода хотябы потому, что абстрактный wasm исполняется ровно тойже виртуальрой машиной что и абстрактный байткод, в который собирается в v8 js код.
wasm может быть более предсказуемым в случае, когда мы сталкиваемся с гарбаж коллектором и типизацией, чего в озвученном выше примере нет от слова совсем. GC задействован минимально. Типизация работает ровно также как в wasm typedArray.
2) простое копирование буфера в канвас, для случаев typedArray на порядок быстрее аналога в webGl. уже хотябы потому, что нет издержек на обслуживание каждого пикселя. webGl дал бы Вам прирост тогда, когда вы бы положили на gpu ваши условрые треугольники позволив gpu их красить самостоятельно. в примере выше обслуживается каждый пиксель отдельно. и тут не может быть ничего быстрее копирования буфера.
Круто проделанная работа, спасибо за статью!
применяются промисы, а это ужасно. Фу‑у-у.
А чем вызвана эта неприязнь?
Я могу предположить что автору не нравится как промисы разрешаются, а именно в конце фазы выполнения кода. Т.е. резолв промиса не отрабатывает синхронно. Обычно это не проблема, но когда у тебя высокопроизводительный движок и очень много операций это может стать проблемой. Вообще далеко не всё в браузере рассчитано на высокую производительность, лично стыкался в ситуацию когда пара тысяч setTimeout начинают жёстко тормозить, при этом на коленке написанная замена которая тикает по фреймам полностью решила проблему.
Я как-то давно пытался на хроме отрисовать график на 10 млн точек. Не получалось, зависал браузер.
А как пытались? На webGL, с подходом как тут описано, когда на CPU стороне лежит буфер размером с экран и он аплоадится каждый фрейм вполне может неплохо получиться. Но в любом случае это будет по сути уменьшением количества точек до того количества, которое имеет смысл отображать.
Я использовал canvas.
Ну я особо не пытался. Понял, что есть ограничения браузера по памяти выделяемой на эту операцию, и при превышении он прерывает операцию чтобы не завесить ПК. Там треблвалось дорабатывать алгоритм, так как вы пишете уменьшать количество точек. Я решил что нужно разбивать на порции или обрабатывать на стороне сервера. Вобщем реально было это решить, но в силу того что я начинающий, я переключился на другие задачи.
То есть уже нужно преобразовывать. У нас 10 млн значений, но для вывода мы имеем только около 2х тыс пикселей в ширину. Соответственно нужно преобразовывать тлчки в вертикальные линии. Как то так, такие мысли у меня были в тот момент.
Статья отличная.
Уровень сложности, правда, вводит в заблуждение: средний или сложный, но явно не простой, как по мне.
Честно говоря, на таких примерах я и начинаю чувствовать магию современных компьютеров. Казалось бы, работаю каждый день с этим, примерно представляю, сколько вычислений нужно, к примеру, на декодирование 4к, перенос кучи данных мгновенно через тысячи километров по сетям, сколько нужно считать для отображения банальных окон и так далее, но только на конкретных цифрах чувствуешь, до какой же степени быстрО то, что показывает мне ютуб перед сном
Ну, тут я ещё не забывал, что то же самое, но на каком-нибудь С или С++, дало бы не 20 миллионов, а, скажем, сто и в полтора раза быстрее)))
Из материала, может сложиться ложное впечатление, будто бы typedArray играют какую-то важную роль в производительности всей задачи. Что может спровоцировать читателя в будущем использовать их вместо типичного ExoticObjectArray.
Вероятно, для информативности, следовало бы добавить, что любые typed array в js только тогда приобретают "мистические" черты супер-производительности, когда такие array можно передавать в неизменном виде в какое либо внешнее API. Например imageData от canvas.
Все же прочее, что делается с темже тайпедАррай, в современных агентах, подобных v8, работает с тойже производительностью. При єтом может быть причиной ее просадки именно в момент формарования отображения тайпед аррай на типичный js код.
То есть условный консоле.лог, примененрый к тайпед аррай, может привести к худшей производительности чем он же к exotic object array.
Эй, а как же мемасы про low level из оригинальной статьи?
Классная статья тоже коллегам кидал в слаке.
Далее добавляем ввод/вывод и возвращаемся в реальный мир :)
А еще вы можете заиспользовать ArrayBuffer и Views
Насколько быстр Javascript? Симулируем 20 миллионов частиц