Чому JavaScript працює швидше, ніж C++?

Чому JavaScript працює швидше, ніж C++?

Так, ви не почулися. Глючний, тупий, гальмований JavaScript працює швидше, ніж С++. Зачекайте тягнутися до return userKarmaVote (), дайте мені можливість все пояснити. Адвокат!

Є три види брехні

Є такий проект під назвою Benchmarks Game. Діти написали програми (обхід бінарних дерев, n-body і т. д.) на всіх популярних мовах програмування і розробили методику вимірювання швидкості і споживання пам'яті. Перш ніж читати далі, прохання ознайомитися з методологією вимірювань.

Реалізація кожного алгоритму докладно описана (наприклад, nbody). Це open-source і якщо ви вважаєте, що якийсь алгоритм реалізований не найоптимальнішим способом, то можете запропонувати власне рішення.

З усіх інтерпретованих мов JavaScipt працює швидше за інші. Він в п'ять разів швидше, ніж Python і Ruby (в тому числі JRuby).

На сьогоднішній день JavaScript - це найшвидша інтерпретована мова в світі.

Повертаючись до C++. За алгоритмом regexdna JavaScipt відпрацьовує трохи швидше, ніж C++. При цьому навантажує CPU в два рази менше, хоча і споживає в два рази більше пам'яті.

За іншими алгоритмами JavaScript, природно, відпрацьовує повільніше C++, але враховуючи що вони спочатку в різних вагових категоріях (компільована мова зі статичною типізацією проти інтерпретованої мови з динамічною), різниця не така вже й велика.

Чому JavaScript такий швидкий?

Інтерпретатори для Python/Ruby були написані обмеженою кількістю людей. Ці люди, можливо, шалено талановиті, але на стадії розробки у них не було ніякої конкуренції. Вони конкурували тільки з собою, зі своїми уявленнями про швидкість і якість. Інтерпретатор же для JS народився в конкурентній боротьбі кращих умов світу. Mozilla розробила SpiderMonkey, Google розробив V8, Microsoft відкрили Chakra. Всі вони працювали в найжорстокішій конкурентній боротьбі.

Коли у команди NodeJS постало питання про вибір движку для JS, вони просто подивилися бенчмарки, побачили що V8 набагато швидше і вибрали його. Якщо завтра Chakra від Microsoft буде працювати швидше Google V8, то не буде ніякої проблеми перейти на нього.

Чому JavaScript такий повільний?

Як було сказано вище, JavaScript як мова - швидка. Однак вважається, що «нативне» призначення JS - маніпуляції з DOM. Насправді це вже давно не так і JS успішно використовується на сервері, в мобільних пристроях і навіть в мікроконтролерах. Але мова не про це. Мова про те, що коли ви за допомогою JavaScript працюєте з DOM, то гальмує не JS, а DOM. Є багато причин, чому DOM такий повільний, але я дозволю собі звузити фокус тільки на одній причині. Проблема в самій специфікації HTML. У розділі 1.1.1 The DOM Structure Model є наступний абзац:

…objects in the DOM are live; that is, changes to the underlying document structure are reflected in all relevant NodeList and NamedNodeMap objects…

Сенс у тому, що об'єкти в дереві DOM - «живі». Це означає, що при будь-якій зміні будь-якої частини DOM ці зміни відображаються в кожному об'єкті DOM.

Великі кампанії, такі як Flipboard, наполегливо боролися з лагами DOM. У підсумку у них нічого не вийшло і вони змогли домогтися 60 FPS тільки замінивши DOM на Canvas. JavaScript нікуди не подівся, а лаги пропали. З цієї ж причини Netflix відмовилися від DOM на своїх TV-приставках, а Реакту довелося придумувати свій «віртуальний DOM».

Ще раз: JavaScript на клієнті не лагає. Додає повільний DOM (точніше маніпуляції з DOM). Не важливо чим ви будете змінювати DOM - джава-скриптом або асемблером. DOM все одно буде пригальмовувати. Саме через гальмівність DOM, JavaScript став вважатися повільною мовою. Це історична несправедливість і від неї давно пора позбутися.

WebAssembly

У зв'язку з цим у багатьох існують невиправдані очікування від приходу WebAssembly. Мовляв, прийде WebAssembly порядок наведе і ми нарешті відмовимося від «гальмованого» JS. По-перше, навіть після приходу WebAssembly робота з DOM залишиться за JavaScript. Так, якісь фреймворки (типу AngularJS) отримають можливість перенести важку логіку на C/C + +, але сумарний приріст від цього буде мінімальним. По-друге, коли WebAssembly зможе безпосередньо маніпулювати DOM'ом, минаючи JS, приросту по швидкості не буде, оскільки гальмує DOM, а не JS.

Хейт

Я розумію, що швидкість роботи - не головний критерій оцінки мови. Потрібно враховувати споживання пам'яті, навантаження на CPU тощо. Я розумію, що одна справа - швидкість роботи якихось академічних алгоритмів, а інша справа - швидкість роботи справжнього продакшн-додатку. Я розумію, що крім алгоритмів є ще патерни і підходи, і що ваш асинхронний ASP.NET може працювати швидше асинхронного NodeJS.

Однак JavaScript вже досить піддався нападкам (заслуженим і незаслуженим) за свою «дивну» поведінку, за своє ставлення до типів, до успадкування і т. д. Але вішати на нього ще й ярлик гальмівності - це перебір. Зупиніться!