Комментарии 65
Не очень понимаю чему тут удивляться. Видя разницу между TypeScript и JavaScript, сразу приходит на ум JIT. Asm.js тоже JavaScript, только сделан что-бы лучше джитился.
Нужно сначала скопилировать его в javascript, который потом запустить в рантайме, который этот самый javascript понимает.
Ну какой рантайм в числодробилках? После JIT-компиляции получаем машинный код.
А вы стали ли бы разбираться, в чем дело, если бы увидели такой отчет?
Тоже мне бином Ньютона. Из названия бенчмарка видно, что это числодробилка.
Как думаете, насколько правильно делать вывод о том, что Swift быстрее Go?
Под Swift находится LLVM, в котором заложены оптимизации, а компилятор Go не использует все современные инструкции процесса.
В числодробилках да.
Не очень понимаю чему тут удивляться. Видя разницу между TypeScript и JavaScript, сразу приходит на ум JIT. Asm.js тоже JavaScript, только сделан что-бы лучше джитился.
А TypeScript не сделан что бы лучше джитился.
Ну какой рантайм в числодробилках? После JIT-компиляции получаем машинный код.
Ну вот этот самый JIT, к примеру, в понятие "рантайма" входит.
Он по построению не может исполняться быстрее чем Javascript. В отличии от asm.js, в рантайме у него информация о типах полностью теряется. Следующие три строчки будут преобразованы в один и тот же Javascript:
const fn = (x : number, y : number) => x+y;
const fn = (x : string, y : string) => x+y;
const fn = (x : number | string, y : number | string) => x+y;
Единственный возможный путь к ускорению за счет статической типизации — интерпретация Typescript напрямую, без преобразования в Javascript. Но так никто делать не умеет, и пока что не собирается.
ваше сложное приложение, написанное средней руки программистом, в сжатые сроки, быстрее не станет.это справедливо для любого языка.
Бенчмарки показывают максимально достижимую производительность. Что важно при выборе языка для некоторых задач.
Писать все время быстрый код, как вы предлагаете программистам – это тоже плохо. Получится что-то нечитаемое и неподдерживаемое. По-моему правильно сначала писать что-то читаемое и поддерживаемое, а потом уже искать места где можно оптимизировать. Получается, что программисты пишут код в одном стиле, а бенчмарки пишутся в другом. Тоже вполне себе проблема.
Можно писать быстрый код, можно писать средний код, но писать говнокод то не стоит.
Это явно говорит о неквалифицированном программисте, который плохо знает javascript
Вот здесь поподробнее
Ну к примеру, написав const o = {width: 5, height: 5} на самом деле у Вас создадится что-то похожее на struct в плюсах, а обращение к полям такого объекта будет сразу выполняться по нужному сдвигу. Но только если вы не делаете какую-нибудь фигню, чтобы всё нарушить, например, будете в одной строчке кода обращаться к объектам разных классов (другие языки вообще чаще это не позволяют).
Вот если вам реально нужно обращаться к разным классам, тогда ок, а без нужды не стоит.
Пример по операциям — "+". Служит и для сложения, и для конкатенации. В мономорфном коде если я написал a + b, то надо, чтобы a и b всегда были числами, или всегда были строками. Тогда именно в этой строчке будет всегда выполняться одна и та же операция (сложение или конкатенация). Соответственно, с точки зрения ассемблера там всё будет просто (к примеру, тупо выполнится сложение и всё).
Кстати, javascript, если что, быстрый и ест мало памяти. А то кто мало разбираются, думают, что он медленный или жрёт много памяти (видимо, смотря, на браузеры, а они такие не из-за JS).
Я не к словам придираюсь, я просто утверждаю что использование или неиспользование кода, который ведет к оптимизации на основе мономорфизма ничего не говорит о квлификации программиста от слова «совсем». А вы говоите, что это очевидно. Не очевидно.
В реальности же, думаю, разница между всякими for была, думаю, на уровне нескольких процентов (с учётом кода, выполняющегося внутри).
Кроме того, тут дело не только в процентах, а ещё и в элегантности кода. Мы отдаём эти проценты не просто так, а чтобы написать хороший код. А вот если бы программист отдавал проценты, но писал такой же по хорошести и даже хуже код, то да, такой программист с for был бы неквалифицирован, в зависимости от того, какая получалась бы просадка по производительности.
одно времяДа, думаю, квалицифированный программист должен в том числе и следить за развитием языка во времени. Необязательно знать случаи, когда конструкция стала на 10% быстрее, а вот если он ускорилась в 2 и более раз, то, думаю, это нужно знать.
Вот, к примеру, появился новый цикл с of. Первое, что я прикидываю — какая у него может быть производительность в будущем. Если понятно, что в будущем компилятор сможет прооптимизировать цикл до стандартной величины, то не так много смысла отказываться от него сейчас. Во-вторых, я меряю, какая у него производительность в данный момент. Ну и в-третьих, я слежу за блогом V8project — если цикл будет прооптимизирован, я об этом узнаю. Особенно я обращу внимание на него в том случае, если до этого он вдруг работал медленно.
В заключение могу сказать, что Вы говорили об оптимизации. А пользователь vintage говорил о деоптимизации. Это разные вещи. В случае с оптимизациями мы специально делаем так, чтобы код работал даже быстрее, чем должен. Т. е. мы были нормальным программистом, а стали супер-нормальным. А в случае, если мы, к примеру, превратим классы в хэши, то код станет работать медленнее, чем должен. Т. е. мы были нормальным программистом, а стали плохим. Преждевременная оптимизация чаще не нужна, но это не значит, что программист должен убивать свой код и делать его в 10–100 раз медленнее, чем должен даже без оптимизации.
Так там же все равно в итоге V8 используется.
Да. И в итоге в тот же ассемблер компилируется.
А значит, и преобразование в Javascript есть, и типы никто не использует для оптимизаций.
Leap of logic, этого оттуда не следует.
Leap of logic, этого оттуда не следует.
Как вы объясните это:
For deno to execute typescript, it must first compile it to JS. A warm startup is when deno has a cached JS output already, so it should be fast because it bypasses the TS compiler. A cold startup is when deno must compile from scratch.
Технически говоря, покуда мы не знаем (или знаем и я что-то просмотрел? Там есть мистическая строчка tsc, но все же) что там этот ts компилировало, можно предположить, что так же этот компилятор использовал какие-то трюки для оптимизации, например, заинлайнив метод doCacl, использовал SIMD или вообще переписал все под asm.js или вообще wasm.
Правда никто не мешает тоже самое сделать и с js (типы только самому придется выводить).
P.S. Как заметили ниже, в коде на ts просто используются воркеры вместо процессов в js.
но это будет не тот JavaScript, который бы написал человек. Я взял ваши функции, прогнал через миллиард циклов и скормил TS-транспайлеру, а копию запустил просто как JS. Версия из транспайлера оказалась быстрее за счет оптимизаций — функция не вызывается в цикле, а просто записана как ряд операторов.
Кроме того, const в TS для данных практически всегда означает подстановку этих данных по месту использования, что дает крохотный, но не гарантированный бонус, особенно если константа используется во множестве алгоритмов — так как вызов локальных переменных в функции происходит быстрее, чем обращение к глобальным.
Какой ключ у tsc делает инлайнинг константных функций? Я почему-то не наблюдаю подобного поведения.
Ну что же, впредь мне наука — проверяй гипотезы тщательнее и не спеши писать посты поздно ночью!
Тест уверенно воспроизводится на моей машине, при установке флага minimize: false в конфиге вебпака — инлайнинга нет. Если же в optimization вообще ничего нет, как в репо, то инлайнинг есть
Но по факту, посмотрите package.json, мы заказываем инсталл только webpack, webpack-server и webpack-cli, и внезапно оказывается, что у нас скрыто подключается terser. Почему тогда мы должны говорить «это делает не вебпак?» Ведь в депенденси нет терсера?
тогда давайте сделаем следующий шаг — «этот комментарий набираю не я, а мои пальцы». )
А насчет философии иерархических включений — надеюсь, что я как человечество, рано или поздно перестану бить сам себе морду, а то получается какое-то сумасшествие. Наверное, поэтому, другие человечества и не спешат заходить в мою солнечную систему и здороваться с таким соседом )
Этот тест открыт для всех, если есть уверенность в том что JS должен не отставать от TS, то надо просто отправить туда свой вариант и его добавят. И несправедливость будет исправлена.
Чтобы удобно следить — для этого там нумеруют конкретную реализацию, так как из-за смены компилятора или библиотеки или ещё чего-то, можно обнаружить, что конкретная реализация неожиданно разогналась или отстала.
По-пунктам:
1) TS vs JS, надо просто отправить код, которому вы верите и он будет принят. В статье много говорится об этом тесте, но причина почему так — не раскрывается. О каком рефакторинге идёт речь — не очень понятно: если задача — поддержать код будущими интернами — то эти тесты не про это.
2) Rust vs Rust, просто игнорируйте версию, которая в данный момент отстала, если она не имеет для вас значение.
3) Swift vs Go, из данного теста очевидно что в настоящий момент Swift опережает Go в реализации mandelbrot и ничего больше, чтобы ~ представить производительность на более широком кругу задач — то надо посмотреть на и на другие тесты. Какие-то из них завязаны на реализаций hashmap, другие — на деревья, большинство — на параллельное выполнение. Все в большинстве относительно простые. Если интересуют более комплексные тесты — то их надо искать не на этом сайте, но тем не менее какое-то относительно точное представление о производительности языков он даёт.
Мало того, финальный документ на их странице показывает свечу с распределением результатов всех тестов для конкретного языка, где можно заметить, что в целом производительность не так сильно отличается, как кажется если смотреть только на топовые цифры.
TS vs JS, надо просто отправить код, которому вы верите и он будет принят.Как может TS быть быстрее JS? Что это сравнение вообще показывает? Я не вижу причины существование этого теста. Полчить правку просто, достаточно TS скопилировать в JS.
В статье много говорится об этом тесте, но причина почему так — не раскрываетсяПричина в том, что не нужно такие тесты вообще писать и публиковать. По факту идет сравнение двух скриптов на JS
Rust vs Rust, просто игнорируйте версию, которая в данный момент отстала, если она не имеет для вас значение.Не могу проигнорировать. Если посмотреть внимательно, то самая быстрая версия в 2 раза быстрее чем предыдущая. А swift быстрее go меньше чем в два раза. Где гарантия, что кто-то кто понимает в go не напишет тест, который ускорит версию Go в два раза? Ведь это уже было с Rust.
Swift vs Go, из данного теста очевидно что в настоящий момент Swift опережает Go в реализации mandelbrot и ничего большеВот это как раз неочевидно. Про это и статья. Очевидно только то, что программист на Swift написал более быстрый код.
достаточно TS скопилировать в JS
Я согласен, именно это и надо сделать и отправить, к сожалению, вопрос JS vs TS меня не сильно волнует, чтобы заняться исправлением этого самому.
Где гарантия, что кто-то кто понимает в go не напишет тест, который ускорит версию Go в два раза
Как это устроено вполне понятно — чем больше вариантов решений для конкретного языка — тем больше можно сделать вывод, что код _приближается_ к оптимальному. Не очень понятно кто кому какие гарантии, в ежедневно меняющимся IT, тут должен давать. Тест показывает то что показывает на настоящий момент. «Где гарантии, что через 5 лет не выйдет специальный процессор под JS, на котором JS обгонит C?» — нет таких гарантий.
Очевидно только то, что программист на Swift написал более быстрый код.
На данном сайте говорится, что это не соревнование алгоритмов, для каждой задачи предоставляет описание каким именно образом это должно решаться, другой вопрос что даже в рамках этого описания есть варианты для оптимизации, как например — в C++ hashmap на шаблонах гораздо эффективнее для небольших числовых ключей.
Я ещё раз добавлю — тест показывает то, что показывает в настоящий момент и ничего больше, но даже из этого можно сделать довольно много выводов — посмотреть на понятность кода, на активность сообщества, на скорость каких-то основных библиотек и тд и тп.
Подробности, код и скриншоты — в короткой заметке
habr.com/post/433230
Буду рад, если вы проверите тесты, и убедитесь сами.
Кстати, Go быстрее чем Rust
Хорошая шютка :D
// Автор статьи "пруфлинка"
Который, собственно, является очередным подтверждением темы статьи.
— Чем?
— Чем Linux!
©
А, простите, чего заминусовали-то? Это ж тоже про веру бенчмаркам
Кстати, Go быстрее чем Rust
Это был сарказм?))
Попробуйте почитать пост по моей ссылке дальше заголовка. А для пущего веселья сравните автора поста по ссылке с автором комментария, на который вы ответили)
А, выше уже написали. В общем, вышло забавно.
Бенчмарки между языками обычно знак скудоумия и бенчмаркер обычно силен в одном своем маленьком мирке=языке, отсюда и идут перлы аля Свифт быстрее Go, Go быстрее Java. Вот когда "медленная" Java на ваших глазах развернет цикл, векторизует в AVX, выравняет данные для лучшей загрузки в регистры и все это в произойдет в момент выполнения когда программа сама поймет что это имеет смысл (tiered jit) в отличие от АОТ — вы все еще будете бенчмаркать Go vs Java?
Программисты помешаны на скорости исполнения программ. Мы следим за скоростью даже там, где эта скорость не очень-то и важна.
Ах, если бы…
К сожалению, мы живём в мире, где всем (ладно, почти) глубочайше насрать на производительность порождаемых ими монструозных уродцев.
О да, последние несколько проектов(так повезло) спрашиваю себя,
почему на рынке еще не появилось ниши "читателей кода".
"Аудит самих себя" не так часто работает. На последних местах — одно и то же:
Прихожу и сижу денек, сжимаясь в страхе от желания все бросить, признав собственную неорганизованность под бесконечным потоком громких слов: "ревью", "тесты", "стейджинг", "митап", "рефакторинг". Потом оборудование, бумажки, неловкая наладка окружения, знакомство с коллективом — сплоченая команда, зовут в бар, отмечать пополнение состава новым коллегой.
Наконец, приходит время смотреть проект:
читать код, "выписывать свои мысли, чтобы сформировать задачи".
И совершенно неочевидно, что делать, если все "очень плохо". В голове две мысли — плевать начальника и стучаться к боссу повыше, либо бежать.
За оклад балансировать между корпоративной этикой и здравым смыслом может не каждый.
Если нужно много операций с числами без потери точности то вместо BigInteger нужно использовать стороннюю библиотеку — так заметно быстрее и меньше памяти требует.
В части сравнений между языками / платформами — видно как рантаймы отличаются между языками
Почему я не верю микробенчмаркам