Комментарии 144
Ждём полноценные десктопные UI-фреймворки. Благо, они либо умеют рисоваться через OpenGL ES, либо можно на взять и отрендерить битмап из памяти.
Да вон оно уже есть https://epicport.com/en/ttd
Оно же на emscripten, а не сабжевом wasm
Фишка emscripten'а в том, что сам инстанциирует нужный код и с точки зрения программиста — нету разницы, что именно под капотом. И при asm.js и при wasm вызов функции происходит совершенно одинаково.
Еще одно преимущество — emscripten сделал реализацию системных вызовов платформы linux(syscalls). Это дает возможность прямо переносить программы, которые обращаются к файлам в web. Обращение будет происходить к виртуальной файловой системе, в emscripten есть несколько имплементаций таких — используй какая больше тебе подходит
Еще одно преимущество — emscripten сделал реализацию системных вызовов платформы linux(syscalls). Это дает возможность прямо переносить программы, которые обращаются к файлам в web. Обращение будет происходить к виртуальной файловой системе, в emscripten есть несколько имплементаций таких — используй какая больше тебе подходит
Строго говоря, не сисколов, а libc
шного API к ним. Хоть оно и маппится почти один в один для простых вещей, это разные вещи.
Я смотрел в исходники и видел там MEMFS
и IDBFS
, как минимум. Думаете в glue-коде для wasm будет принципиальная разница? Наверняка те же имплементации fs будут и для wasm варианта.
А чому нет. Автоматически снимаются проблемы песочницы, кроссплатформенности и установщика.
https://habrahabr.ru/post/325102/
http://vps2.etotheipiplusone.com:30176/redmine/projects/emscripten-qt/wiki/Demos демкам уже несколько лет же
Наконец будет неблокируемая исполняемая реклама.
Появятся тяжелые программы в вебе, о которых мы сейчас и мечтать не можемага ядрёна вирусы,( загружающихся в память, во время исполнения- из за неведомого переполнения) зашифрующие диск(загрузочную область) за время нахождения на сайте при прокрутке какой нибуть 3 d картинки.
Появится закрытый проприетарный код.
Если js, пропущенный через uglifyjs еще как-то можно читать, то c wasm это будет сделать гораздо сложнее. А если сайт взломают негодяи и как такой код найти и разобрать?
Вирусов не будет. Если бы была возможность они существовали бы уже сейчас. Суть в том, что нужно смотреть на то, какие API браузер предоставляет для JS окружения. То же самое API будет доступно со временем и для WebAssembly. Т.е. ничего нового не добавят
В 2011-м году браузеры добавили поддержку для произвольного доступа к папкам и файлам на HDD без участия юзера. Но потом это выпилили, по всей видимости из соображений безопасности.
Так что боятся нечего, живем!
Разработчики антивирусов смотрят в недоумении и удивлённо пожимают плечами.
А разработчику зачем искать код вируса? Перезалил приложение и прописал права доступа как правильно, а не как всегда :-)
Там DOM же отдельная сущность, за пределами js. Не думаю, что что-то изменится принципиально, а вот появление рендеринга в стиле десктопных gui библиотек с отрисовкой через web-gl думаю можно ожидать в будущем.
Поисковики скажут большое спасибо таким приложениям.
А зачем индексировать, например photoshop? Или IDE? Тут ведь речь скорее о суровых приложениях, а не сайтах.
А зачем пилить UI на web-gl? HTML для этого гораздо лучше подходит. А вот операции с большими массивами данных лучше перенести в WASM. Получим гибкий интерфейс и быструю логику.
По большей части из-за DOM, в котором сейчас все проблемы. Иерархичность, вложенность элементов никогда не была необходимым условием существования UI. Сейчас HTML выражает одну парадигму, судя по низкой производительности DOM, не всегда применимую.
Мне кажется что в след за WASM появится какой-нибудь вариант типизированного DOM, который будет более предсказуем и менее затратен по памяти. Мобильные платформы в это очень нуждаются, а значит это привлечет интерес крупных вендоров.
Ну это из разряда научить зайца курить. Можно, но зачем. DOM довольно точно и прямоленейно выражает идеи html — тем и ценен. Возможно надо попробовать отказаться от самой html+css разметки. Как мне кажется все эти модные вещи типа flexbox это именно попытка упростить вложенность и перегруженность современного html.
Например Хабравская лента комментов может быть сделана иерархично, когда каждый новый уровень вложенности достигается оберткой его в относительно текущего с фиксированным padding. А можно сделать их без вложенности с прямым вычислением смещения (похоже так и сделано).
Да и сам html… В текущих условиях это выглядит странно. Предлагаю нажать ctrl+u и увидеть сколько в тексте непосредственной информации, а сколько разметочной. Особенно разбалансировано выглядит лента комментов. А теперь представте, что у нас есть возможность скомпилировать всю разметочную информацию в удобный для браузера вид? В какой-то мере современный мир к этому движется, генерируя элементы на лету из JS, но только выглядит это странно: генерацией html и вставкой в текстовом виде в dom дерево, с последущим парсом и отрисовкой
Давайте вспомним, что HTML это история не про приложения, а про документы. Здесь важна семантика от того и богатство возможностей каждого элемента. Но скоро появятся Custom Elements, и это уже будет шаг в сторону оптимизации HTML под приложения: вы сможете отдать с сервера древовидную семантическую структуру, а отобразить одномерным списком. После этого вопрос останется в том, чтобы дать разработчикам возможность более низкоуровневых оптимизаций.
А они и так игнорируются. Веб жеж.
Условно говоря, если мы совсем забиваем на браузер, то мы рисуем на канвас не только своим шрифтом, но и своим растеризатором шрифтов со своим хинтингом и алиасингом, сами мигаем курсором, сами рисуем выделение и рассчитываем сколько пикселов глиф занимает.
Уже есть товарищи которые свои шрифты на Canvas используют и получают за счет этого неслабые преимущества по сравнению с конкурентами — OnlyOffice тот же https://habrahabr.ru/company/teamlab/blog/141434/
За счет чего могут например нормально редактировать большие документы (чего Office365 / Google Docs не могут).
А если я люблю slight hinting, а full hinting не выношу, то я могу это у себя в настройках системы включить. А в этом веб-приложении?
Если даже нельзя из JS получить данные — ну галочку сделают если будет так нужно.
Альтернатива в данном случае — DOM-based редактор типа Google Docs который просто не способен работать корректно в некоторых случаях (один из них — большие документы).
PS. экспериментировал с wasm. Пока если его использовать — то надо использовать по-крупному — т.е. выносить сразу большой кусок кода. Иначе похоже много времени тратится на вызов функций из js, Написал на wasm (не компилил, писал сразу на нем, только в текстовом формате) функцию для работы с int64. Нам в ONLYOFFICE очень нужна такие вычисления. Так вот. пока wasm проигрывает в скорости эмулятору int64 на js. А там такой огород! (храню в двух интах и работаю с ними, верхняя/нижняя часть и так далее). Но работает. Ждем улучшений. Канвас ускорился в разы с момента появления. И тут думаю все будет отлично.
Можно libfreetype свежий с собой таскать и не иметь проблем. А шрифты сейчас и так уже повсеместно используют не системные, а загружаемые.
Прийдём к тому, что для того, чтобы мигать курсором, нам нужно будет выделенное ядро.
Зачем же так грубо. Не целое, а всего 30%.
Ну вот тема внезапно получила неожиданное развитие :-)
Есть подозрение, что весь rust рантайм один в один скомпилирован в wasm. Думаю это пройдет со временем.
Смотря что под рантаймом понимать.
https://www.rust-lang.org/en-US/faq.html
Does Rust have a runtime?
Not in the typical sense used by languages such as Java, but parts of the Rust standard library can be considered a “runtime”, providing a heap, backtraces, unwinding, and stack guards. There is a small amount of initialization code that runs before the user’s main function. The Rust standard library additionally links to the C standard library, which does similar runtime initialization. Rust code can be compiled without the standard library, in which case the runtime is roughly equivalent to C’s.
#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
not(target_os = "freebsd"),
not(target_os = "macos"),
not(target_os = "bitrig"),
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
not(target_os = "openbsd"),
not(target_os = "solaris")))]
#[cfg_attr(test, allow(dead_code))]
pub mod guard {
pub unsafe fn current() -> Option<usize> { None }
pub unsafe fn init() -> Option<usize> { None }
}
тобишь его нету для emscripten-target.
Stack unwinding можно не использовать (тобишь zero-cost), а если надо исвользовать то в си будешь юзать примерно такой же код.
heap в Rust юзается аналогично си, в языке даже никаких операторов для этого не встроено, просто в std есть парочка стандартных контейнеров шоб не лепить свой велосипед как это часто делаетя в си.
в языке даже никаких операторов для этого не встроено, просто в std есть парочка стандартных контейнеров
Box это не то что бы прям обычная структура: https://www.reddit.com/r/rust/comments/5j05j6/magic_box/
Да и рано или поздно, но нормальный box-синтаксис вернут, а Box::new
объявят устаревшим костылем.
На мой взгляд идея крутая как и asm.js для написания именно библиотек/виртуальных машин, насколько я вижу они будут работать очень быстро(относительно быстро).
Но для реализации конечного продукта системные языки типа rust и с/с++ слишком не выразительны будет сильная потеря в производительности труда. По этому, интересно поддерживает ли данный модуль сборку мусора, которая в общем то есть в Rust? Насколько я понимаю память организуется как JS массив и управляется непосредственно модулем/приложением? Если уже реализована сборка мусора будет круто перенести на данный модуль ScalaJs, ClojureScript и др. нуждающиеся в автоматическом освобождении памяти.
Сейчас модель памяти сишная, то есть без сборки мусора, но с указателями и адресной арифметикой.
Спасибо был не до конца осведомлен, я знал что Rust утилизирует память не явного участия программиста но не знал что это выполняется отличным от GC механизмами.
Если кому-то интересно: https://www.rust-lang.org/en-US/faq.html#is-rust-garbage-collected.
Сборщик мусора можно и свой написать. Я уже частично портировал свой Java-JavaScript компилятор в WebAssembly: https://github.com/konsoletyper/teavm
Это позволит отправить JavaScript на то место, для которого он и задумывался — анимировать снежинки и связывать компоненты на странице. Языки со статической типизацией начинают доминировать после определённого объёма проекта — динамику сложно анализировать и рефакторить.
Ну не знаю, очень неудобно работать со спецификаторами времени жизни, читать практически так же трудно, как J. Возможно, это от непривычки, но я с растом 1.0 знакомился когда он только вышел — было тяжко понять, что вообще происходит.
А их никто не заставляет прописывать на каждый чих — в большинстве случаев они вполне подходят умолчательные и указываются только там, где ситуация нестандартна. Да и из практики скажу — не так уж они сложно читаются — просто ещё один вид параметров, достаточно легко отличимый от других и на ход выполнения программы не влияющий.
Мне кажется, что для WASM должен появится новый язык транслируемый в С, а в дальнейшем компилируемый для других платформ. Т.е. для которого WASM будет первичен и избавлен от наследия, и при этом возьмет самое лучшее от современных разработок: транспиляцию вместо макросов, минималистичный синтаксис как в Go, централизованый репозиторий и т.п. Трансляция в C позволит создать ОС прямо в браузере, как пример.
Библиотеки на разных языках будут интегрироваться на уровне WAsm.
Но WAsm — не серебряная пуля, проблемы интеграции, создававшиеся специфичным рантаймом языков останутся. Одна из сложностей крутится вокруг разных подходов к управлению памятью.
Создание при этом отдельного языка — вопрос ортогональный. Сколько угодно — лишь бы хватало энтузиазма :-)
«ОС прямо в браузере» — сомнительная затея, проистекающая видимо из непонимания целей создания WebAssembly и закладываемых в него возможностей и ограничений. ОС будет просто «тесно» в таких условиях, да и смысла — 0, чем эта ОС будет управлять, если её саму держат в песочнице?
Про emscripten это и так понятно. Но разработчиков на C, D, Go, Rust, C# будет трудно объединить из-за идеологических разногласий, и здесь нужен аналог С для unix. Это мое мнение.
ОС прямо в браузере – это во-первых пример. Во-вторых, снижение порога входа в разработку это не "сомнительная затея", а спусковой механизм к расцвету технологического разнообразия, пример которого мы наблюдаем сегодня благодаря появлению персональных компьютеров.
Про emscripten это и так понятно. Но разработчиков на C, D, Go, Rust, C# будет трудно объединить из-за идеологических разногласий, и здесь нужен аналог С для unix. Это мое мнение.Вы не понимаете, что делает emscripten. Он берет LLVM IR код и транслирует его в вид, понятный виртуальной машине JS. Соответственно, любой фронтенд, генерирующий IR код (rust, clang, mono, llst…), сможет быть использован для веба.
Я прекрасно понимаю что делает emscripten, но проблему это не решает, у каждого языка свой рантайм, вы захотите использовать одновременно модули, написанные на Go, Rust, Java если к каждому оверхед + несколько десятков мегабайт? Думаете, да? Посмотрите что сейчас происходит в том же linux, каждый язык поддерживает свой собственный зоопарк модулей зачастую выполняющий идентичные функции, потому что мало кто хочет использовать в проекте больше одной платформы. Язык это не просто форма представления, это несколько больше, это огромное количество логических примитивов, особенностей работы и философия. Наглядный пример Objective-C и Swift, я регулярно слышу от мобильных разработчиков фразы, вроде "может такой модуль есть на свифте?". Так что не стройте фантазий на тему того, что все языки заживут дружной семьей внутри WASM. WASM лишь выведет гонку языков на новый уровень.
Многие языки просто делают обёртки вокруг системных библиотек. Сами системные библиотеки пишутся на разных языках, но предпочтение отдаётся тем, которые работают эффективней. Понятное дело, что большинство написано на C/C++, но есть примеры и библиотек на Фортране. Хотя, конечно, велосипедостроителей — тоже хватает. Но раз это устраивает соответствующие сообщества, то в чём проблема? Типовые наборы для платформ будут, как сейчас популярные библиотеки JS и веб-шрифты, грузиться с CDN и с большой вероятностью будут уже кешированы в браузере.
Go, Rust и Java самих по себе будет сложно подружить. Но как альтернативный язык решит проблему? Почему бы всем разработчикам не перейти на тот же Rust? Но они не хотят, их по тем или иным причинам устраивают родные Go, Java и прочие. То же самое и с каждым другим языком из длинного списка.
Ещё один язык как решит эту проблему? Будет ещё один язык, на который никто не хочет просто так переходить, тыкая своим богатым багажом наработок, накопившимся за десятилетия, в противовес молодой и малоразвитой экосистеме. Вот в чём весь вопрос.
Поэтому вопрос конкуренции языков никуда в ближайшей перспективе не денется. И его не решит дорогостоящий проект по созданию ещё одного самого лучшего языка, на котором не будет своих нужных модулей.
Причём даже его тотальная совместимость с тем же С и сишными библиотеками не решит проблемы языков, создававшихся, чтобы уйти от С. С++ — своя песочница, требующая написания специальной прослойки для совместимости с С. Rust — своя песочница со строгим контролем памяти, создававшаяся, чтобы избежать проблем С и С++. Обойма языков с GC — отдельная история — создававшаяся для избегания необходимости управлять памятью и проще писать код, даже серьёзно жертвуя производительностью. Какое из этих сообществ легко согласится пожертвовать своей песочницей в угоду возвращения к уровню С?
вы захотите использовать одновременно модули, написанные на Go, Rust, Java
вов-вов, какой Java? wasm расчитан на те случаи когда производительности JS нехватает, а не для того чтобы привести зоопарк языков в браузеры.
разработчиков на C, D, Go, Rust, C# будет трудно объединить из-за идеологических разногласий
И введя новый язык мы заставим всех ненавидеть его одинаково из-за чего "идеалогические разногласия" пропадут? (:
заставим всех ненавидеть его одинаково
Это вы откуда взяли?
Вы не понимаете, что убедить людей использующих go отказаться от него в пользу C#, равно как и обратное, представляется невозможным. А вот предложить и тем и другим альтернативу, которая будет эффективно решать поставленные задачи, вполне возможно.
А вот предложить и тем и другим альтернативу, которая будет эффективно решать поставленные задачи, вполне возможно.
"Это вы откуда взяли?"
Кто-то в восторге от "простоты" Go и терпеть не может "перегруженность" С++//D/Rust, для кого-то сборка мусора принципиальный вопрос, кому-то подавай выразительности, кто-то рад дополнительным гарантиям раста и считается дополнительную сложность адекватной ценой. Вот какой должен быть новый язык, чтобы всем угодить?
Недовольные останутся на том, что есть. Тех же кто захочет получить профит от вышеперечисленного не смутит отсутствие некоторых фич. Суть именно в том чтобы получить усредненный результат, а не тащить все и сразу. Тот же rust также появился.
Недовольные останутся на том, что есть.
Ну так я о том и говорю, что фрагментация только увеличится. Если, конечно, новый язык не будут навязывать, усложняя жизнь остальным.
Тот же rust также появился.
Раст совершенно не похож на "усреднённый результат" и привносит уникальные (по крайней мере, для около-мейнстрима) фичи.
Здесь просто напрашивается картинка про 15-й стандарт.
Ну, будет ещё один язык, который будет точно так же бороться за место под солнцем с C, D, Go, Rust, C# (и далее длинный список выше не упомянутых, но относительно популярных языков от Паскаля до Хаскеля). Чтобы стать по-настоящему популярным, ему потребуется выйти за пределы Wasm и начать применяться в других областях (или рано или поздно найдутся энтузиасты, которые его туда притащат.
С другой стороны сделать качественный и непротиворечивый язык — это весьма сложная задача. И язык должен решать задачи программиста, а не задачи платформы, иначе ему ничего не светит. Дальше — задача распространения языка, обучения специалистов, создания необходимого множества библиотек (в современных языках это достаточно большое множество), создание своего менеджера пакетов, создание IDE (задача на самом деле не менее ресурсоёмкая, чем создание самого языка).
Вы уверены, что все эти затраты — действительно стоят того, чтобы получить лишь немного лучше подходящий для конкретной ниши язык, возможности которого с лихвой перекрываются уже существующими более универсальными языками?
Нет, я не против того, чтобы появился ещё один язык, который будет на голову выше своих конкурентов и станет языком будущего, затмив другие решения. Но я точно знаю, что это не простая инженерная задача, и в современных реалиях под силу лишь солидному и хорошо финансируемому коллективу, без очевидных гарантий успеха.
Посмотрите на пример Rust — его уже не один год разрабатывает достаточно крупный коллектив. Разработка идёт очень открыто в тесном сотрудничестве с сообществом и это сообщество делает немалый вклад в развитие экосистемы. Но совершенно очевидно, что даже при таком участии большого количества людей сделать качественный современный язык — достаточно непростая затея. Убедить людей перейти на него, когда их в целом устраивает их текущий язык, с которым они делают бизнес и сильно зависят от него, накопив большое наследие и опыт — непростая затея.
После этого можете оценивать шансы и необходимость ещё одного языка, а тем более его шансы стать хорошим языком.
Странный вопрос, затем чтобы можно было подключать сишные либы, пока своя кодовая база не наполнится.
Что мешает эти сишные либы компилировать в тот же LLVM IR?
Для начала аргументируйте в чем преимущество использования IR. Но возможность скомпилировать библиотеку с помощью gcc важна для сообщества разработчиков открытого ПО как таковая.
При описанном мной подходе, я не вижу никаких препятствий для поддержки разных способов компиляции.
Скомпилируйте, пожалуйста открытую библиотеку Apache Lucene с помощью GNU GCC, если это столь принципиальная проблема, чтобы любой проект был компилируем GCC. Или предложите альтернативу. Подскажу, clucene и sphinx сильно отстают по функционалу, а lucenecpp загнулся.
А если вам не нравится LLVM IR, то используйте любое другое intermediate representation, никто не мешает иметь что-то подобное в результате работы фронта и оптимизатора gcc (за исключением самого gcc, конечно, если это ещё не вылечили). И дальше скармливать emscripten'у как бэкенду компиляции в asm.js/wasm.
Это не проблема языка, то что Apache Lucene не может быть скомпилирован в gcc. Строить вавилонскую башню не вижу никакого смысла. Количество языков не должно быть слишком большим, чтобы не убить прочие плюсы, именно поэтому я и говорю о возможности трансляции в C наравне с WASM.
в чем преимущество использования IR
LLVM создавался как универсальный компилятор и в настоящее время имеет бэкенды для большого числа языков. Это своеобразный инструмент, позволяющий избегать велосипедостроения в достаточно сложной области — создании оптимизирующего компилятора под разные платформы.
Конечно, если смотреть на С/С++, для них существуют более эффективные компиляторы (тот же GCC для примера). Но эти компиляторы не так универсальны и их архитектура не позволяет их сделать настолько же универсальными, как и LLVM. Поэтому LLVM IR — такой себе лингва франка, в развитие которого вкладываются усилия многих сообществ и корпораций.
Это, к слову, о едином стандарте для разных языков: LLVM — один из кирпичиков этой универсальности. И такие языки как Python, получили свою дорогу в WAsm именно благодаря ему.
Поэтому чтобы запустить Servo в браузере — придется имплементировать abstraction layer на API, доступном в браузере. Нечто подобное происходит, когда вендор портирует Android на свой девайс(делается имплементация HAL)
Их полно на любой вкус, начиная с Питона и заканчивая Явой.
Чтобы «зацепиться» за опять модное слово ассемблер?
Сколько ассемблер
А с wasm — типы известны еще до исполнения программы.
Еще один минус JS — нету нативной поддержки Int64. Все числа в JS — double, под значащую часть выделяется только 56 битов и 8 бит под мантису. Из-за этого большие int64 округляются до 2^56 и теряется точность. А wasm поддерживает int64 из коробки
Поддержка int64 и вообще чисел произвольного размера добавлена в предложения.
На самом деле 53 и 11.
«на вид-то он хорош, да зелен — ягодки нет зрелой» © :-)
Были б проверки для математики "не так страшны", так бы не бились над языками и алгоритмами для исключения лишних проверок откуда только возможно. Ветвление само по себе плохо сказывается на оптимизации производительности, поскольку нужно предсказывать по какой ветви пойдёт вычисление, но ещё и сокращает эффективность кеша — больше кода, более рыхлый код, больше данных (информация о типе), соответственно меньше оседает в более производительном кеше процессора.
И одна к другой таких проблем у JS много, как бы ни был крут JIT, ухитряющийся иногда выжать производительность всего-лишь на порядок худшую, чем у нативного кода.
"нет ветвлений" и "проверка" — это взаимоисключающие параграфы.
А кто сказал, что оно одиночное? Если мы в цикле складываем элементы массива — ок, тут простая ситуация. Но обычно не это называют "математикой".
более крутом динамическом связывании через таблицы
Опять же, динамическое связывание — это противоположность того, что необходимо для достижения высокой производительности. Но эта тема уже выходит за пределы парадигмы языка, созданного быть динамическим, так что требовать от JS прыгнуть выше головы — нет смысла.
Поэтому, собственно, и появился WAsm, — для заполнения этой лакуны, способный генерировать код близкий по производительности к нативному, в том числе благодаря возможности статически всё прописать и оптимизировать.
Васм появился скорее потому, что сам жс более многословный и его нужно было ужать во что-то более компактное. Асм был хорош, но очень уж толст и его приходилось долго грузить и парсить, а с типизацией там в принципе все было ок (хотя и не идеально, некоторые проверки оставались)
от dll никуда не убежишь нельзя же все монолитом собирать
Тут немного не то. Сами библиотеки могут подключаться динамически, но таки их интерфейс быть статическим, соответственно код остаётся статически анализируемым и оптимизируемым.
Но динамическое связывание вполне может быть и в монолитном бинарнике. Всё, что ведёт к определению типа в рантайме, проверкам в рантайме — всё это бьёт по производительности и надёжности.
WAsm позволяет избежать именно этого вида динамичности и достигнуть пределов возможного — полной отдачи от процессора. Но это не означает, что саму динамичность он исключает, нет — он даёт выбор, который был крайне беден в JS и появилось хоть что-то с asm.js.
Эволюция самого JS — тоже достаточно радующий факт. Возможно через несколько лет мы получим стандарт достаточно продуктивного языка. Но наследие со всеми странностями, нелогичностями и проблемами — ещё долго будет тянуться. Хотя, какой-нибудь очередной strict mode
и транспилеры могут решить эту проблему.
Я никогда не спорил с тем, что динамическое определение типов ведет к лишним накладным расходам, но динамическое связывание это все-таки не о том.
Так и жс позволяет избежать этого вида динамичности благодаря развитию JIT.
Тогда, возможно, мы просто говорили о разных вещах, ок.
JS не позволяет избежать динамичности в силу того, что у него просто нет соответствующих инструментов. И JIT, каким бы он ни был умным, не сможет из ничего сделать статическую проверку и оптимизацию. Речь ведь не только про конкретные типы переменных, речь про сам алгоритм.
В Rust мы можем выполнить проверку варианта с перечислением через match
— компилятор будет точно знать, что значение не может содержать ничего лишнего, "проверка" сведётся лишь к проверке значения дискриминанта и в соответствии с этим значением будет выбрана конкретная ветвь. Компилятор может статически проанализировать ход исполнения и убедиться, что какие-то ветви вообще не будут задействованы и просто исключить их. Компилятор может заранее вычислить все статические преобразования и убрать их из кода, заменив на вычисленные значения. Таким же способом он может вооще исключить вызовы функций, либо заинлайнив их код, либо в процессе упрощения выражений вообще сократив, как ненужные (что проблема для JS, который должен свериться с виртуальными таблицами методов у объектов). Много таких оптимизаций, которые возможны благодаря заранее и однозначно размеченному коду. Сюда же свобода от сборщика мусора — память управляется однозначно и предсказуемо, а большое количество типов не требуют отдельного выделения памяти в куче.
Всё это то, чего JS не может предоставить компилятору в силу своей парадигмы динамического языка, максимально простого для пользователя. Сам же JIT — тоже требует времени на компиляцию, которая в случае компилируемых языков происходит заранее. Причём оптимизация может занимать времени в разы больше, чем сама компиляция (в случае с Rust это легко может достигать показателя "на порядок дольше") — в каком-то смысле это роскошь для JIT, хотя у него есть и свои, недоступные обычным компиляторам возможности.
Asm.js я здесь не рассматриваю, поскольку не знаю случаев, чтобы он напрямую использовался в разработке, а не как цель компиляции из других языков. Возможно, где-то, в особых случаях такое происходит, но это всё-таки скорее исключения, чем норма, и было бы интересно услышать опыт тех, кто этим занимался.
было бы интересно услышать опыт тех, кто этим занимался
Это боль =) Если серьезно, то немного математики туда впихнуть бывает очень удобно, кода получается меньше чем если компилить из с. Но если проект большой, то не вариант. Но в принципе оптимизации асм работают и не в асм режиме, так что можно для математических функций просто сделать аннотацию типов, работать с типизированными массивами вместо обычных и в целом это будет уже как гора с плеч для компилятора.
Всё это то, чего JS не может предоставить компилятору в силу своей парадигмы динамического языка, максимально простого для пользователя
JIT делает предположения и по сути оставляет небольшое поддерево из всего множества вариантов, самое главное не разрушить его ожидания. Да JIT дорогой и время инициализации от этого растет, но не время выполнения. Скажем для игр это не так критично как для магазина одежды.
В целом — я согласен, что WAsm достаточно близок к asm.js. Тут не о чем особо спорить: первый — развитие идеи второго и логическое его завершение. Просто не могли в конечном итоге не придти к представлению в виде байткода, поскольку это самое удобное и компактное представление, уже подвергнутое предварительной оптимизации, и не могли не сделать его максимально близким к низкоуровневой платформе.
Я, конечно, не исключаю, что оптимизатор JS может проанализировать код и убедиться, что тип не должен поменяться — в такой ситуации можно выбросить проверку и это как раз хорошо скажется на производительности. В конце концов, за счёт чего-то таки потрясающих результатов таки добиваются.
WebAssembly — это больше про сам байт-код, а не про виртуальную машину с JIT. Стандарт кода, интеграция с другими API браузера, изоляция веб-приложений. Байткодовую машину тоже с нуля никто не изобретал — она уже есть в браузерах для JS. Теперь же это всё (или ещё не совсем всё) упорядочено и стандартизировано.
Вместе с маркетинговыми заявлениями про [задуманную] нативную производительность и компактный размер.
Исходники интерпретатора на OCAml тоже вполне можно посмотреть.
Так что все это новый велосипед, хотя можно было действительно взять V8 и ее байт код.
WASM это в первую очередь универсальная библиотека, которую можно встроить в любой язык Python, JS, Ruby, C. Другими словами она не привязана к браузеру и может использоваться как элемент любых приложений, в том числе и десктопных. Например уже сейчас появился проект перевода криптовалюты Ethereum на WASM, что уже многое говорит о заложенной в эту нее (библиотеку) универсальности.
Библиотека это API, но я вижу только JavaScript API
С другой стороны, любой JIT может встроиться в адекватный по ABI язык/софтинку.
Но только в области скриптинга, боюсь, места давно заняты. Даже внедряемый режим TinyC — с компиляцией в нативный код уделает простой интерпретатор байт кода в десятки раз.
На самом деле это очередная драка за монополию за код в браузере — JavaApplets похоронили, Silverlight похоронили, Flash закапывают, освобождают место.
Потому пока что этот васмовский байт код засунули интерпретироваться в JS-машинку в браузере (хоть куда нибудь). Чтобы попытаться потом вытеснить и JS.
Кто сможет сожрать JS — получит много денег.
Сейчас мы делаем standalone веб-приложение по распознанию и анализу японского текста с изображений. Распознание производится с помощью tessaract, который через emscripten был скомпилирован в asm.js код.
Распознание в хроме без поддержки asm.js: 9.17 секунды
Распознание в фаерфоксе с поддержкой asm.js: 3.19 секунды
Это не считая времени на инициализацию 2.8 мегабайт js кода
Теоретически, при появлении wasm результат будет 1.2 секунды в любом браузере, а инициализация модуля будет быстрее (и весить он будет меньше).
Не нужно ничего качать и устанавливать, достаточно зайти на сайт и быстренько распознать интересующий кусок текста, и с применением того же метода можно тут же увидеть анализ текста:
Поэтому на данном этапе можно сказать, что wasm это не замена js, не работа с dom (сам dom к js имеет слабое отношение, поэтому ускорение js не дает ускорение dom), а дополнение к текущим возможностям, без которых было бы менее удобно.
С приходом wasm станет ли доступно управление TCP сокетом из браузера? Чтобы не использовать websocket.
Появились энтузиасты, которые хотят ускорить reactjs засчет rust и wasm (ссылка).
Пробежался глазами по ссылке, но так и не понял как они собираются этого добиться?
По идее же все опять упрется в тормознутый DOM? Не очень понимаю откуда ускорение должно взяться.
Как один из возможных вариантов оптимизации: если использовать текстовые шаблоны, Rust может сделать работу с шаблоном очень эффективной (наполняя строковой буфер, а не создавая тучу промежуточных строк в куче). Генерация же DOM-дерева через .innerHTML
, это обычно более оптимизированная операция, чем поэлементное добавление узлов с помощью JS. Не знаю, насколько это хорошо стыкуется с достаточно популярным JSX.
code/decode между строками и буфером будет довольно дорогим
Почему? Что сделает его дорогим? Строка по сути и есть буфер. В любом случае одно преобразование — это значительно дешевле, чем масса промежуточных аллокаций на каждый объект JS. Тут уже нужно закапываться в устройство React
и детально изучать возможности, поскольку сложно что-то утверждать на основе догадок и предположений. Посмотрим, если у "энтузиастов" получится то, что они задумали — это будет хорошим знаком и примером, который будет стоить изучить всем. Хотя они вполне могли и ошибиться, неверно оценив задачу.
Эффективнее хранить шаблон в теге шаблона и потом его клонировать и вставлять в дом. А вот дерти-чекинг виртульного дома операция вполне математическая и очень тяжелая, ее теоретически можно скинуть в васм если придумать как tries закодировать в линейную память.
прийдется каждый символ строки превращать в число, потом передавать в васм и там с ним работать и потом возвращать обратно и снова превращать в символ и клеить из этого набора символов большую строку
Не совсем понимаю суть операции. Строки в Rust — это массивы байт, которым гарантируется, что они являются корректным utf-8. Их не требуется дополнительно преобразовывать в "символы".
Кроме того, сами шаблоны вполне могут работать в режиме байтовых массивов, им не требуется быть полноценной строкой.
Да, я про само представление строк в JS не подумал, там таки UTF-16.
Ну, никто не заставляет преобразовывать их в utf-8. Если у нас на входе будут корректные массивы байт с UTF-16 строками в шаблонах и значениях, то они же будут и на выходе. Хотя соответствующие примитивы для парсинга шаблонов в Rust придётся "завелосипедить".
нужно из строки создать массив значений
Строка в представлении JS — и есть массив значений. Технически какой-нибудь аналог Vec<u16>
или Vec<Utf16Char>
. Преобразования не требуется, (разве что чисто номинальное, чтобы получить в Rust необходимый тип), данные уже являются набором байт (как и вообще всё в памяти машины).
Операции элементарные, но дорогостоящие, особенно склейка
В том и суть, что Rust позволяет делать склейку дёшево — в едином буфере, что многократ эффективней, чем создание множества промежуточных строк, как это делается в JS. Точно так же Rust может склеивать и байты и массивы произвольных типов, "наливая" их последовательно сразу в конечный массив. В результате на выходе мы имеем уже готовую строку, которую только и остаётся передать в JS.
Именно поэтому я и предположил, что вынесение в Rust задачи шаблонизации, позволит достичь существенной экономии. Всё-таки этот язык создавался в том числе и для скорости, что достигается за счёт низкоуровневых операций, обычно недоступных в высокоуровневых языках.
из типизированного массива, а он о строках ничего не знает.
Вы хотите сказать, что проблему создаст сам JS, выполняя некоторую бессмысленную работу? Тогда согласен, тут всё будет сложнее, нужно подробней изучать, как всё устроено, в том числе как получается этот типизированный массив и обртно строки из него.
Со стороны Rust подобных проблем не будет, поскольку он может прозрачно "трансмутировать" тип значений в массиве.
Но вообще, линейная трансформация строки, имхо, менее затратная операция, чем масса аллокаций в процессе обработки шаблона. Но тут уже решающее слово за бенчмарками.
А может даже и велосипедить не придётся, всё-таки Rust создавался с мыслью о создании браузера.
Генерация же DOM-дерева через .innerHTML, это обычно более оптимизированная операция, чем поэлементное добавление узлов с помощью JS. Не знаю, насколько это хорошо стыкуется с достаточно популярным JSX.
На начальном рендере это так, но последующие обновления дешевле делать «атомарно» через DOM api (насколько я знаю, реакт так и поступает)
Вообще-то наоборот. Вот рассказ об этом, например: https://youtu.be/TXqiq5tOWRQ?t=3604
И именно поэтому React получается быстрее обычных шаблонов на том же Handlebars.
2. Эм… пойду учить Go наверное
Пробуем делать web-frontend на Rust (WebAssembly)