Comments 133
Python, опечатались
Стокгольмский синдром.
Давно задумываются и не только, просто это очень долгий процесс
Вот откуда берется стремление все писать на JS — вот загадка. Ну, то есть понятно, откуда, учить другие языки лень. Но все же.
Просто такое ощущение, что это как раз вам как следует разобраться во вселенной JS/CoffeeScript/TypeScript лень)
JS — на данный момент один из самых востребованных языков. Хорошие разработчики JS получают в среднем больше, чем плюсеры, например. Не думаю, что весь мир сошёл с ума, а вы один умный. Это маловероятно.
Впрочем, взгляд мой не слишком обоснован, ибо, как вы справедливо отметили, мне действительно лень в его вселенной разбираться.
Как и разработчикам из других языков (которые тоже у них когда-то были первыми) очень лень учить JS, поэтому они страдают от детских болячек при работе с JS и клянут все на свете за callback-hell и асинхронность.
В JS такое же программирование, как и в любом другом языке. Если перестать к нему относиться как к языку, на котором всплывающие окошки делаются, а постараться применять общепринятые в разработке подходы и паттерны, то ничего в нем страшного и неудобного нет. По крайней мере не больше, чем в любом другом языке.
Как понять что мобильное приложение написано на js? оно запускается секунд 10 и тормозит. Серьезно, все эти Slack, gitter и еще десяток js мобильных приложений наводят на меня тоску. Хорошо фейсбук вовремя соскочил с жс и перешел на натив.
оно запускается секунд 10 и тормозит.
В статье как раз объяснили, что проблема не в js.
Я наблюдаю что обычно для мобильного «веб» приложения используют css фреймворки и куча html — тысячи элементов DOM. Если в нативном приложении выводить тысячи виджетов то оно тоже будет тормозить.
И наоборот, сделайте веб-приложение с «10-дивами» и оптимальным кодом — оно будет быстрое.
Проблема в головах. В JS популярны огромные фреймворки (мегабайт исходников сейчас — минимум) с неэффективной архитектурой (на каждый чих дёргаем проверку всего состояния). Ну и запуск WebView с полным фаршем веб технологий внутри — тоже не бесплатен.
Да какая мне разница что там тормозит, для меня как обывателя каждое js based приложение продолжает доказывать что тормоза — они там где рядом есть JS.
Последний айфон, железо гипермощное, а я вынужден пялиться 10 (десять, Карл!) секунд в белый экран чтобы открылся gitter.
Казалось бы причем тут намеренное замедление, еще и такие же жс "кодеры" плюсуют. Забавные вы.
А сделайте лучше хорошее мобильное приложение, чтобы я забрал свои слова назад.
На iOS — 18 тысяч классов, порядка сотни мегабайт, FBEventUpdateNotificationSubscriptionLevelMutationOptimisticPayloadFactoryProtocol-Protocol.h.
На Android — жуёт аккумулятор жутко, воплей полный интернет.
Тут, скорее, в руках дело.
Я до сих пор ума не приложу, как можно было написать приложение так, что его лоадер просто не мог переварить и пришлось его патчить на лету? На любом языке, при желании и умении, можно сделать так криво, что оно будет тормозить не реально.
Какая связь между кол-вом классов и скоростью работы? меня на iOS вполне устраивает нативный клиент по сравнению с жс.
CoffeeScript и TypeScript давно всё решили.
Клиент-сайд для мобилок и десктопов на js — вообще отличная вещь, если что.
То, с чем копаются обычно xaml-щики/шарписты и прочие гораздо легче и красивее делается на js/html5/css3
JS обычно начинают хейтить после знакомства со своим вторым языком =)
А потом, при углублении оказывается что новый x-lang не так уж и удобен, а JS не так уж и плох, когда знаешь как его готовить.
Но не сказать бы что я его любил… До появления promises, lodash-underscore и Typescript (классы более человеческие и не надо постоянно писать «длинные» return & function). Просто сейчас JS, особенно с сахаристыми надстройками, очень удобен для функционального программирования и отложенной обработки. Просто не знаю, что есть лучше, читаемее и лаконичнее в этом плане. Возможно Ruby, но у JS ещё и быстродействие)
При разработке сайта fullstack разработчиками, проще писать на одном языке, чем переключаться между ними, поэтому javascript появился еще и на бекенде. А потом дошла очередь и до мобильных с десктопом.
Были бы альтернативы и тогда JS не был бы настолько популярным. Например, на движке Unity3D можно разрабатывать на JS и на С#. К тому же, первоначально документация и примеры были в основном на JS. Спустя несколько лет C# вырвался в лидеры с огромным отрывом.
Мне самому нравиться C# и Pascal/Delphi, но пишу на JS, т.к. работаю front-end разработчиком.
Главный вопрос, почему все так сильно любят JavaScript?
Не JS, а веб. Полагаю, это дань моде — делать приложения для веб, даже если они ужасны.
Ведь в нём так много неудобных вещей… и чтобы писать что-то серьезное уже нужен какой-нибудь TypeScript с классами и типами...
Скорее, непривычных. Этому языку на самом деле не нужны классы, и не надо на нем писать классы. Объекты, структуры, функции, но не классы. Как только мы хотим писать на JS в ООП стиле, нас мгновенно начинает ломать оттого, что там нет ни наследования, ни инкапсуляции, ни даже полиморфизма. Если мы хотим строгое ООП, нам мгновенно становится нужна и статичная типизация, иначе наши классы постоянно ломаются без сохранения структуры, и привычный синтаксис, чтобы простые (ООП-) вещи делать просто, без извращений вроде самовызывающихся функций и локальных массивов методов(!).
На самом деле JS прекрасен своей простотой и лаконичностью, не зря JSON-нотация вышла за пределы самого языка. Да, у нас нет классов, у нас есть только эти непонятные прототипы, но у нас есть объекты — и ничего, кроме объектов. Нам не нужно писать целый класс только для того, чтобы написать hello-world (как это заставляет делать Java), у нас и числа, и функции — всё является объектом, и мы можем писать в функциональном стиле. У нас нет различия между объектом и массивом (привет, Java, с твоими arr[i] и list.get(i)), у нас нет различий между массивом и картой (PHP, это я тебе шлю привет с твоим «this function preserves keys»), у нас даже обыкновенные числа — это объекты (Java, спасибо за примитивы и боксинг\анбоксинг для коллекций примитивов). Наконец, у нас есть возможность модифицировать объекты на лету и нам не надо генерировать 100500 классов на каждый чих. У нас нет указателей и арифметики указателей (Си, слышишь?) и сегфолтов.
Просто не надо использовать язык для того, для чего он не был изначально предназначен, не нужно нам жирных клиентов ООП, фреймворками, MVC и «многопоточностью». Это скриптовый язык. Или давайте еще bash ругать, что на нем нельзя писать большие и сложные приложения.
Нам не нужно писать целый класс только для того, чтобы написать hello-world (как это заставляет делать Java)Точно так же про JS можно было бы сказать, что для запуска программы на нем нужно сделать html-страничку с тегом <script> и открыть ее в браузере, или npm-модуль. В данном случае, класс в Java — это не архитектурный оверинжиниринг, а способ разделить код на модули. В некотором смысле это даже проще, чем в JS — нет разделения на «глобальную» и «локальную» области видимости, весь код в методах, а все методы в классах.
У нас нет различия между объектом и массивом (привет, Java, с твоими arr[i] и list.get(i)), у нас нет различий между массивом и картойОсновное преимущество массива как структуры данных — это быстрый доступ к произвольным элементам и компактное расположение в памяти. Если эмулировать массив с помощью таблицы с числовыми ключами, как это сделано в JS или PHP, то оба преимущества теряются. Как только нужно обработать существенные объемы данных, кажущаяся простота выстреливает в спину и приходится изворачиваться с помощью костылей. Например, в JS на самом деле не один тип массива, а один объектомассив и еще девять отдельных типов массивов. В этом свете система типов Java выглядит куда более лаконично.
В цивилизованных языках типа Scala / Kotlin / C#, кстати говоря, есть перегрузка операторов индексации, которая решает проблему.
Просто не надо использовать язык для того, для чего он не был изначально предназначенВот с этим полностью согласен. Основная критика JS и PHP возникает из-за того, что их стали использовать в качестве инструментов серьезной промышленной разработки, вопреки неизбежной обратной совместимости с ранними версиями, которые были сделаны на коленке и не подразумевали такой ответственности. Но это исторический факт и с ним ничего не сделаешь.
это не архитектурный оверинжиниринг, а способ разделить код на модули
Деление на модули там, где модули не требуются — это и есть оверинжиниринг в чистом виде. :) Отсутствие функций вне классов — это глупость, которой нет оправдания.
Например, в JS на самом деле не один тип массива, а один объектомассив и еще девять отдельных типов массивов.
В джаве с типами тоже не очень сладко: имется зоопарк Stream, IntStream, LongStream, DoubleStream… про зоопарк функциональных интерфейсов вообще молчу. В шарпе получше, но числовые типы всё равно существуют отдельно друг от друга, что печаль. Так что красивые системы типов начинаются где-то в районе функциональных языков. Вся мультипарадигма и мейнстрим обрастают кошмарными костылями.
Отсутствие функций вне классов — это глупость, которой нет оправдания.Наоборот, если Java изначально создавалась как объектно-ориентированный язык для энтерпрайза, вводить сущности для описания редкой на тот момент функциональной парадигмы было бы нецелесообразно. За двадцать лет ожидания выросли, и теперь поддержка ФП считается необходимым минимумом. А еще через 10 лет будем удивляться, как мы писали без зависимых типов и автоматической системы доказательств теорем.
В джаве с типами тоже не очень сладко: имется зоопарк Stream, IntStream, LongStream, DoubleStream…Это случаем не из-за type erasure такое происходит?
В шарпе получше, но числовые типы всё равно существуют отдельно друг от друга, что печаль.Можно чуть поподробнее? Вы о том, что примитивные числовые типы приводятся друг к другу отдельными командами, и `Decimal` не является встроенным, или что-то другое?
А еще через 10 лет будем удивляться, как мы писали без зависимых типов и автоматической системы доказательств теорем.
Вы оптимист. :)
Это случаем не из-за type erasure такое происходит?
Да, большинство проблем с функциональщиной упирается в джавовую реализацию дженериков. Потоки умеют работать с бокснутыми типами, но не с примитивными, а это убивает производительность. И если количество типов потоков ограничено, то количество интерфейсов вообще экспоненциально взрывается.
Вы о том, что примитивные числовые типы приводятся друг к другу отдельными командами, и Decimal
не является встроенным, или что-то другое?
Я про невозможность написать T Sum<T> (T a, T b) where T : Number => a + b
.
Я про невозможность написать T Sum<T> (T a, T b) where T: Number => a + b.Это и правда было бы очень удобно. Даже проблем на первый взгляд не видно, но всю картину портит тип
Decimal
, который выглядит как встроенный, но с точки зрения CLR обрабатывается совершенно по-другому.Так что пока придется вместо
T
в вашем примере писать dynamic
:)В некотором смысле это даже проще, чем в JS — нет разделения на «глобальную» и «локальную» области видимости, весь код в методах, а все методы в классах.
Просто в JS мы не видим эту всю «обвязку», которая в Java пугает новичков. А разделения в традиционном смысле и нет — играет роль принцип матрёшки, точно так же в Java мы можем создавать вложенные классы.
Если эмулировать массив с помощью таблицы с числовыми ключами, как это сделано в JS или PHP, то оба преимущества теряются.
Конечно, за архитектурный подход приходится платить, так же, как платим, работая с примитивами, которые объекты, или строками-объектами — вместо того, чтобы работать с самими данными и их последовательностями (я имею ввиду, что строки не являются просто массивами символов). А именно, проигрываем в скорости и по памяти, по сравнению с C\C++, например.
В цивилизованных языках типа Scala / Kotlin / C#, кстати говоря, есть перегрузка операторов индексации, которая решает проблему.
Каким образом? По-моему, перегрузка операторов не решает проблему сравнительно сложного внутреннего представления.
Но, на самом деле, нам это и не нужно. Например, мы теоретически можем написать (серверное) веб-приложение на C или даже Ассемблере, используя старый добрый CGI — но зачем, когда есть более простые Java\PHP\ASP.NET\Python (даже старый добрый Perl, в конце концов).
Что касается JS — мы имеем простой и очень лаконичный язык, с минимумом исключений из правил (имея ввиду сам язык и его парсер), сравнимый по простоте с Lua. Костыли и другие ухищрения появляются, как только мы хотим сделать из него универсальный язык, таща из него сахар и привычные приблуды из других языков, а также столь милое сердцу тру-ООП. При этом забывая, что это не Java, не C++ и даже не C#.
Проблема в том, что пропагандисты прототипов и противники классов в жабоскрипте не отвечают на простой вопрос: "А как жить-то?"
Нормально написанный код на прототипах вполне себе однозначно преобразуется в код на классах. То есть в голове-то можно держать что угодно, а по сути всё равно работа происходит с классами, и разница только сводится к непривычному синтаксису. Цепляться за синтаксис? Но зачем?
Если же код к классам не преобразуется, если используется какая-то магия, которая доступна только при прототипах, но в ООП, то код превращается в кашу, и в любой компании вас за такое творчество расстреляют на месте. Кроме того, подобный код поломает оптимизации современных компиляторов, которые предполагают вполне себе конкретные классы, и производительность проседает, если начнать творить что-то сильно динамическое.
Итого, практической пользы от прототипов ноль, а во всех случаях нормального использования они однозначно преобразуются к классам. Соответственно, возникает вечный китайский вопрос: ана ху а? Так ли ценна примитивность?
Просто в JS мы не видим эту всю «обвязку», которая в Java пугает новичков.Мне очень нравится, как эта проблема решена в LinqPad. Вообще, в C# тоже весь код размещается в методах и классах, как в Java. Но можно выбрать один из трех режимов — «выражение», «блок кода» или «программа». В первых двух случаях пользователь просто вводит код, а уже среда подставляет его внутрь тела метода Main и выполняет. Язык же от этого особыми правилами не усложняется.
Конечно, за архитектурный подход приходится платитьЭто плата не за архитектурный подход, а за золотую пулю. Синтаксически разница между
{}
и []
все-таки есть и логически они используются для разных вещей, но под капотом они реализованы с помощью одного примитива и одно можно превратить в другое. Особенно иронично, что при этом arguments
не является полноценным массивом.По-моему, перегрузка операторов не решает проблему сравнительно сложного внутреннего представления.Я имел в виду проблему, что похожие вещи синтаксически описываются по-разному.
Что касается JS — мы имеем простой и очень лаконичный язык, с минимумом исключений из правилС точки зрения одного синтаксиса это правда. Но если также рассматривать семантику, систему приведения типов и стандартную библиотеку, в JS фантастически много неожиданных поворотов.
Костыли и другие ухищрения появляются, как только мы хотим сделать из него универсальный язык, таща из него сахар и привычные приблуды из других языковЯ признаю, что JS по-своему красив, некоторые вещи в нем сделаны достаточно элегантно. Но если нужно строить небоскреб, а у вас в руках только розовый пластмассовый совочек, то будь он хоть самым прекрасным совочком в мире, вы знатно намучаетесь. Даже если в результате всё получится, это будет ваша личная заслуга и героизм, проявленный вопреки всем козням инструментария.
Лучше всего с задачей превращения JS в приспособленный для разработки крупных проектов язык, на мой взгляд, справляется TypeScript. С одной стороны, большая часть заведомо абсурдных ситуаций отсекается на этапе компиляции, а с другой — он выглядит наиболее «родным», практически не вмешиваясь в существующую экосистему.
Это плата не за архитектурный подход, а за золотую пулю.Синтаксически разница между {} и [] все-таки есть и логически они используются для разных вещей, но под капотом они реализованы с помощью одного примитива и одно можно превратить в другое.
Всё принесено в жертву мантре «всё является объектом».
Я имел в виду проблему, что похожие вещи синтаксически описываются по-разному.
Эта проблема особенно досадна в Java…
Но если также рассматривать семантику, систему приведения типов и стандартную библиотеку, в JS фантастически много неожиданных поворотов.
Увы, да. Думаю, JS мог бы быть проще, чем есть. Возможно, это архитектурный просчет.
Но если нужно строить небоскреб, а у вас в руках только розовый пластмассовый совочек, то будь он хоть самым прекрасным совочком в мире, вы знатно намучаетесь.
В том-то и дело, что не стоило бы на скриптовом языке растить «небоскрёбы», что мы и наблюдаем сейчас. Особенно в этом выигрышно смотрятся такие строгие языки, как Java или C#, предлагая компромисс между простотой языка и его мощью, ухитряясь прятать костыли так, что не нужно по ним ходить каждый день, достаточно на первых порах набить шишек и жить спокойно.
Лучше всего с задачей превращения JS в приспособленный для разработки крупных проектов язык, на мой взгляд, справляется TypeScript.
Да, но, к сожалению, его всё равно необходимо превращать в JS вместе со всеми вытекающими.
В цивилизованных языках типа Scala / Kotlin / C#
Достаточно холиварное утверждение. Особенно, если вспомнить, что и Scala и Kotlin нацелены на ту же JVM, и там предстают во всей красе все сложности реализации, что хорошо заметно, например, если декомпилировать сгенеренный ими байт-код в Java-код и попытаться сравнить с аналогичным Java-кодом.
А еще вспомним такие языки, как Python и Ruby — они не менее прекрасны, однако тот же Ruby (насчет Python я не в курсе) — не самый быстрый.
по алгоритму regexdna JavaScipt отрабатывает чуть быстрее, чем C++
В C++ версии используется re2 с lookbehind
, atomic groups
, possessive quantifiers
, а в V8 это встроенная имплементация с довольно урезаным функционалом?
lookbehind, atomic groups, possessive quantifiers
Ни одна из этих фич в regex dna не используется.
в V8 это встроенная имплементация с довольно урезаным функционалом
Имплементация V8 — это полноценная имплементация JS RegExp. JavaScriptовые регулярные выражения действительно не поддерживают разные фичи, которые поддерживает re2, но обратное тоже верно — например: JS поддерживает zero-width positive lookahead
(?=...)
и backreferences \n
, а re2 — нет. Ни одна из этих фич в regex dna не используется.
Разумеется, по ссылке теста видны регекспы. Но ведь именно из-за поддержки этих фич, иначе устроен процессинг.
backreferences \n,
Ну тут должно быть просто, так как backtracking так и так есть, поэтому такая фича должна быть почти бесплатной.
А вот что вы имеете в виду под zero-width positive lookahead? Ведь любые lookahead
и lookbehind
это zero-width match
?
Но ведь именно из-за поддержки этих фич, иначе устроен процессинг
Отнюдь. Различия между re2 и irregexp действительно фундаментальные — но они отнюдь не из-за поддержки этих фич.
Вот, например, lookbehind в irregexp сделали недавно и никакой особой заморочки с этим не было.
Для простых регекспов из этого бенчмарка основное преимущество V8 состоит в том, что irregexp транслирует регулярные выражения в машинный код, а не исполняет их на «интерпретаторе», как многие другие regexp движки.
Ну тут должно быть просто
На самом деле нет. Вот что на это отвечает Russ Cox (автор re2)
The lack of generalized assertions, like the lack of backreferences,
is not a statement on our part about regular expression style. It is
a consequence of not knowing how to implement them efficiently. If
you can implement them while preserving the guarantees made by the
current package regexp, namely that it makes a single scan over the
input and runs in O(n) time, then I would be happy to review and
approve that CL. However, I have pondered how to do this for five
years, off and on, and gotten nowhere.
https://groups.google.com/d/msg/golang-nuts/7qgSDWPIh_E/OHTAm4wRZL0J
Иными словами в re2 выбраны и реализованы только те фичи, которые можно эффективно исполнять гарантируя линейную сложность, без катастрофического отката
А вот что вы имеете в виду под zero-width positive lookahead? Ведь любые lookahead и lookbehind это zero-width match?
Они так просто часто называются.
Кстати, lookbehind
(?<=re)
re2 тоже не поддерживает, если верить документации :)Ёмаё, стыдно то как, а ведь на самом деле в pe2 не всё поддерживается. Беглым взглядом я пропустил, что это альтернатива к движкам с backtracking механизмом. Отсюда и сложность с внедрением backreference. Жаль старые комментарии редактировать нельзя на хабре.
Было также интересно почитать про irregexp. Lookbehind сделан на базе read_backward, действительно просто и удивляет почему раньше это не было сделано.
Возможно в V8 регулярное выражение компилируется прямо в машинный код, благо движок JIT рядом. А C++ re2 так не может и, по сути, тут уже он оказывается интерпретируемым.
Звучит очень неправдаподобно. Есть ссылочка на тест?
Или что тест просто считает много регекспов?
Бред, общим. JavaScript тормознутый, посмотрите на тесты где тестируется что-либо кроме прямых биндингов на C код, типа регулярных выражений. Особенно советую смотреть не только на скорость выполнения а и на память.
посмотрите на тесты где тестируется что-либо кроме прямых биндингов на C код
Покажите, посмотрим.
Реализация PHP слишком хитрая — там читерство с потоками и она запутаннее, чем js. Найдётся умелец, который перепаяет js на потоки и расстановка сил снова изменится. А вообще в тесте соревнуются в скорости pcre-движков, только и всего, и учитывая что многие используют libpcre — разница Python, PHP и C++ должна быть минимальна. Аналогично, там есть тест с числом пи, где по сути сравнивают производительность очень оптимизированной библиотеки gmp саму с собой, которая написана, к слову, на Си и ассемблере.
Но делать такие далеко идущие выводы на основе самого сомнительного бенчмарка (там ключевое слово — game)...
Зато желающие могут поупражняться в сравнении разных реализаций регулярок — те же peg попробовать или генератор парсеров yacc, который оттранслирует все выражения в чистый сишный код и лишь компилятор ему судья.
Про это все знают, но оптимизациями новых фич в v8 планируют заняться несколько позже, емнип.
Наверняка имеется в виду такие штуки как https://github.com/codemix/fast.js
Он явно не проверяет отрицательные значения на входе (которые должны считать с конца), не конвертирует аргументы в числа.
Кстати, я не уверен что он до сих пор быстрее на свежем v8 =). Проверять надо.
Ага, JIT-компилятор умеет генерить более оптимальный код чем компилятор..
JIT compilation is a form of dynamic compilation, and allows adaptive optimization such as dynamic recompilation – thus in theory JIT compilation can yield faster execution than static compilation.
Кроме того, в среднем, языки со сборщиком, выделяют/освобождают память быстрее, чем языки с ручным управлением памятью (за это приходится платить предсказуемостью загрузки ЦП в данный, конкретный момент).
По моему впечатлению, часто работает правило: «быдлокод на JavaScript быстрее быдлокода на C/C++», это не столько минус C++ сколько закономерное следствие его дизайна, который, во многих случаях, как раз хорош.
Например, если сравнить девелоперский build Unity игры на webgl (он на чистом яваскрипте) с production build (а он — на asm.js), то у второго FPS на 15-20% выше.
Так вот в девелоперском билде такой директивы нет (специально перепроверил сейчас)
И, хотя код тот же самый, но в девелоперском билде он исполняется интерпретатором js, а в production — прогоняется через AOT компилятор.
На счет директивы — вы думаете ее специально отключают? С какой целью? Это ведь одна строчка в коде выставляемая emscripten которая вряд-ли экономит время сборки. Сейчас тоже проверю на чем-то простеньком.
Что касается отключения AOT в девелоперском билде, полагаю, это сделано с целью облегчения отладки в браузерном дебагере. Хотя точно не знаю зачем.
JIT, конечно есть. Тут я был неточен. Но я хотел сравнить js без AOT и webassembly (где AOT есть всегда).
>Наличие директивы «use asm» никак не влияет на отладку. При открытом отладчике FF иногда отключает AOT компиляцию, но на отладку это не влияет
Возможно, это было просто предположение.
>Я проверил ради интереса — в обоих случаях работает AOT компиляция, так что все осмыслено и директива остается на месте.
А директива «use asm» у вас тоже есть в коде в обоих случаях? В моих девелоперских билдах её нет.
Если она у вас есть, то, видимо, мы используем разные настройки девелоперских билдов.
Если её у вас нет, то как именно вы определили, что AOT работает в обоих случаях?
Публичные версии юнити пока не умеют компилировать в WebAssambly (есть демо angry bots, но оно сделано внутри компании).
Я ошибочно связал два факта — существенную разницу в скорости и наличие директивы use asm в production билде при её отсутствии (ну нет её там!) в девелоперском.
FF, действительно влючает AOT несмотря на отсутствие директивы. Интересно, кстати, почему.
>Публичные версии юнити пока не умеют компилировать в WebAssambly
Да, но для целей сравнения скорости достаточно сравнить asm.js и обычный js. Потому что на даный момент WebAssembly — просто бинарное представление asm.js и работает оно ровно с той же скоростью. Разница лишь во времени на скачивание, разархивирование и парсинг. Всё это происходит при инициализации. А дальше скорость одинакова.
Скоростью загрузки и разбора — вполне.
От чистого яваскрипта они оба по скорости работы должны отличаться одинаково.
Почему JavaScript работает быстрее, чем С++?
Очевидно потому что авторы конкурирующего кода на С++ умеют писать на плюсах хуже, чем авторы V8 (или какой движок JS там использовался).
Давайте начнем с того, что язык не может быть медленным или быстрым. Медленным или быстрым может быть ваш рантайм, ваш JIT-компилятор, ваш интерпретатор и т.п.
В случае JavaScript я часто слышу понятие «движок». Так вот, мы можем говорить о производительности движков, но не о производительности языка. Так вот:
- чем запускают ваш JavaScript?
- кто вам сказал, что он интрепретируется, а не компилируется?
- кто вам сказал, что описанные методики и результаты корректны?
Далее, о том, что синтетические бенчмарки ни о чем не говорят — известно уже очень давно.
Чтобы реально говорить о том, что быстрее и почему, а не разбрасываться словами, надо смотреть, почему именно. Искать корень того, почему ваш бенчмарк не может работать быстрее, смотреть, во что упирается разгон тестируемого кода. В статье я ничего такого не вижу.
Давайте начнем с того, что язык не может быть медленным или быстрым
Положим, всё-таки может. Ну невозможно сделать нестрогую динамическую типизацию быстрее строгой статической. Можно совершать огромные рывки, заменяя интерпретацию на компиляцию, например, но в долгосрочной перспективе языки очень заметно делятся на классы по скорости.
(Оставляю за скобками web assembly и прочие костыли, которые по сути кодируют один язык с помощью другого и не предназначены для использования программистом напрямую.)
Но нет такого свойства у языка — «скорость».
Скорости — нет, системы типов и прочие архитектурные особенности, ограничивающие реализации в оптимизациях — есть. К чему городить сложные словесные конструкции?
Ну, можно ограничить возможности языка, заставив программиста отказаться от плюшек, и нагородить костылей, тем самым предоставив компилятору возможнсоти для оптимизации на уровне плюсов. Но на практике такой фигнёй мало кто страдает, так как это уже другой язык получается, поэтому у языков вполне себе есть "скоростные особенности", которые со временем принципиально не изменяются. Как плюсы были быстрыми, шарп жрал память, а похапэ тормозил, так и останется навсегда.
Если рассматривать JavaScript в отличных от браузера окружениях, то объектная модель браузера и объектная модель документа могут не поддерживаться.
О, прикольно. Я в 2010-м году про этот же тест и эту же benchmark game писал. JavaScript V8 и тогда всех выигрывал по regexdna. Меня тогда заминусовали, и я удалил пост. До сих пор стыдно :(
https://github.com/josephmisiti/awesome-machine-learning#javascript
А JRuby почему медленный? Groovy компилируется в Java с использованием своих пакетов, но тем не менее от этого не страдает и даже позволяет использовать его на серверах. Как тогда JRuby действует?
Что же касается фразы «JS быстрее C++», то это вполне возможно даже если считать генерируемый JIT-ом код. Java не даст соврать. Пока, конечно, на длинных дистанциях у Hotspot конкурентов нет, но ничто не мешает прикрутить подобный механизм к V8. Хотя вряд ли кому придёт в голову это делать — требования к потребляемой памяти и скорости генерации кода у серверного и клиентского бэкэндов совсем разные. Скорее научат Java и C# генерировать IR-код для универсальной машины WebAssembly.
Как аргумент — проект максимально быстрой библиотеки регулярных выражений, с JIT, SIMD и всем этим. По словам автора этот написанный на C++ проект всё же опережает безусловно очень быстрый движок RE V8 в тесте regexdna.
https://github.com/coreperf/rejit
Еще раз: JavaScript на клиенте не лагает. Лагает медленный DOM (точнее манипуляции с DOM).
Из этой фразы можно подумать, что проблемы только в DOM, лагает он и все тут. А как только его ускорят, все фреймворки залетают.
DOM медленный, но есть тот же mol, который работает с реальным DOM напрямую и судя по todomvc бенчмаркам (раз, два), гораздо быстрее многих фреймворков вроде реакта и ангулара. Дело в том, как изменения в стейте отражаются на DOM, в цене минимизации обновлений, а это уже архитектурные проблемы на стороне фреймворка.
Ускорив DOM, можно только замаскировать эти проблемы, задвинуть их на второй план.
Почему JavaScript работает быстрее, чем С++?