Про быстродействие Python2 и Python3 написана глупость. Общеизвестно, что Python 2.7 заметно обходит по быстродействию Python 3.0 — Python 3.6 почти на всех задачах. И только в Python 3.7 (который официально ещё не вышел, но бета-версия уже давно доступна для тестов) смогли достичь уровня производительности Python 2.7 и даже местами его превзойти.
Нет, наличие отдельной абстракции «система исчисления» — это совсем не принципиальный нюанс. Т.е. это не базис библиотеки, а скорее надстройка над базисом (в принципе очень похожим на то, что в статье, разве что набор базовых единиц тут произвольный — вот это действительно чуть более абстрактный подход), представляющая собой просто наборы популярных предопределённых единиц.
А вот действительно принципиальным отличием является тот факт, что данная библиотека отрабатывает на этапе компиляции (она построена с помощью метапрограммирования), а не исполнения. Т.е. если записывать какие-то формулы физических расчётов в C++ коде, то компилятор просто не даст собраться программе с неверное (с точки зрения единиц измерения) формулой.
Еще одно отличие (и для моей конкретной задачи это было важно) — в той библиотеке нет функционала «сконвертируй 180 см в ___ футов + ___ дюймов». Там это нужно реализовывать в коде собственного приложения.
Это да. Но это потому что собственно в технической (научной, инженерной и т.п.) практике такое обычно не используют, вне зависимости от системы единиц. Т.е. если у нас есть допустим 1,5*10^3 м, то мы можем это красиво записать как «1500 метров» или «1,5 километра», но не как «1 километр 500 метров».
Читая начало статьи (там где про физику и т.п.), думал предложить в комментариях сравнение с этим www.boost.org/doc/libs/1_67_0/doc/html/boost_units.html. Но увидев далее в статье PHP код, понял, что это будет слишком жестоко. )))
Описанная автором задача является очень распространённой в программирование и соответственно уже давно имеет хорошо проработанное решение с общеизвестным названием. Странно только что автор нигде его не обозначил. Это всем известный конечный автомат.
Смешная статья. 99% перечисленных вкусностей Rust'а имеются в C++, причём большинство уже очень давно. Если автору так это всё нравится, то совершенно непонятно где он был все эти годы — на другой планете, где нет C++?
И да, у Rust'а имеется ряд преимуществ над C++. Это и более строгая работа с памятью и нормальное метапрограммирование (а не корявые вычисления на шаблонах) и т.п. Но про это в статье нет ни одного слова…
Результат внешне очень похож на Boost.Spirit, разве что чуть более многословный. Но при этом насколько же проще оно выглядит внутри! Синтаксические макросы безусловно намного более удобный инструмент метапрограммирования в сравнение с шаблонами C++ (что впрочем совсем не удивительно, т.к. при создание шаблонов о МП никто и не думал).
Но вот пример для mock какой-то странный. Если уж мы там выделили в тестируемом коде работу с веб-сервисом в отдельную функцию (LogError), то никакие IWebService нам уже не требуются, т.к. мы можем банально завести переменную lastError и писать в неё прямо в классе TestingEntryAnalyzer.
Понятно, что это всё демонстрационные примеры для статьи. Но они всё же в них должен быть логический смысл — если используем mock, то должна быть видна потребность в таком решение.
Ну вы, наверное, каким-то не кошерными дистрибутивами Linux пользуетесь :) Попробуйте Debian Stable, там все хорошо.
Вот как раз с такими и игрался. Советую попробовать не обновлять подобный дистрибутив 1-2 года и потом запустить обновление…
Да и последние версии Windows весьма стабильны, несмотря на повсеместное использование динамических библиотек.
В Windows как раз не особо употребляется совместное использование динамических библиотек. В системый каталог кладётся только их малое число, а большинство устанавливается в каталог приложения. Так что под Windows у каждого приложения используется своя версия (и на одном компьютере их может быть множество). Хотя и там изредка бывают проблемы из этой области (обычно когда сомнительное ПО прописывает себя в path), но гораздо реже… Только вот это следствие не умной системы зависимостей, а наоборот уход от неё. Точно так же как и на OSX.
Начинаем ходит кругами :)
Мои представления о компоновке правильные, а если они у вас другие или просто не достает знаний в этом вопросе это ваши проблемы.
Я уже несколько раз описывал вам причины выбывании части языков из обзора. Вы же все с типом компоновки никак не разберетесь. Давайте может вы уже закончите свои увлекательные эксперименты, а пока оставим эту тему в покое? :)
Вот что меня действительно поражает, так это ваше полное игнорирование оценок статьи, а так же этой беседы в комментариях — у вменяемого человека хотя бы из-за них возможно закрались бы какие-то сомнения в собственно правоте. Но у вас ни малейших не появилось. Но вы правы в одном: действительно пора заканчивать — мне уже наскучило стучаться в эту стену…
Динамическая или статическая компоновка это всего лишь инструмент в арсенале разработчика и им нужно уметь пользоваться.
«dll hell» это следствие неразумного использования динамического связывания и было возможно только в бестолково спроектированных системах. Т.е. это проблема системы, а не самой технологии связывания. Модульность (или пакеты) с зависимостями на определенные версии других модулей/пакетов прекрасно работает.
И что же это интересно за толково созданные системы, в которых нормально работает модульность? Надеюсь речь не про Линух, который не раз дох у меня полностью от банального обновления…
Я вижу у вас возникает много вопросов на эту тему… В статье речь идет о сравнении ЯП, а не об тонкостях использования того или иного связывания. Это оффтоп, предлагаю вам все-таки воспользоваться гуглом или почитать специальную литературу.
В статье на основание не верного представления автора о вопросах компоновки (чего только стоит сравнение размеров исполняемого файла при разных компоновках) делаются вполне однозначные выводы о выборе языков программирования…
В первую очередь, конечно же, пользователям приложений. Зачем им его перестраивать при выходе новой версии Java? Скомпилированный бинарь будет прекрасно работать на новой версии JVM, а может быть еще и быстрее если разработчики ее оптимизировали. Или вообще на другой JVM и все это без перекомпиляции.
Что-то похоже у кого-то в голове путаница между пользователями, админами и разработчиками. Нормальные пользователи не то что не занимаются подобным, они даже не поймут о чём речь.
Или зачем пользователем приложения на C++ его перекомпилировать (и потом не все же приложения open source), если создатели C++, например, взяли и поменяли имплементацию unordered_map (исправили баги, оптимизировали).
Для C++ это вообще не работает, т.к. там большая часть кода (включая unordered_map) является шаблонами.
Да все те же:
— жирные бинари (смесь логики и рантайма)
— кросплатформенность
— стабильность рантайма
Хм, что за глупости? Рантайм там даже меньше чем у C++ выходит. И со стабильностью тоже всё хорошо — язык уже устоялся, в отличие от Rust.
Тем не менее в D меня заинтересовала возможность компиляции в LLVM: github.com/ldc-developers/ldc
Но, к сожалению, эта ветка развивается не очень активно, и у меня полезли какие-то странные баги при запуске скомпилированного бинаря, например под Linux на Windows и наоборот. В общем до стабильной работы там похоже должны пройти еще десятилетия.
Это всё какие-то эксперименты, официальным решением для D является компилятор dmd. И у него со стабильностью всё отлично.
Этот азбучный момент в статье, естественно, не затрагивался, но если кратко то динамическая компоновка должна использоваться всегда когда можно, а статическая только в редких специфических случаях.
О, очередное шедевральное высказывание в дополнение к статье… Конечно же зачем нам статическая компоновка, если в ней нет ни замедления работы, ни раздувания дистрибутива, и главное в ней нельзя насладится такой очаровательной вещью, характерной для динамической компоновки, как dll hell.
Такой подход позволяет свободно менять рантайм языка без перекомпиляции приложения.
Осталось только уточнить одну «мелочь»: кому и зачем это вообще надо? )))
Это все достаточно серьезные недостатки на мой взгляд (в контексте моих изначальных, в начале статьи, требований к языкам), и по-этому они выбыли из обзора.
Что-то не увидел описания причин выбывания языка D.
Что касается Rust'а, то ему действительно можно предъявить определённые претензии, являющиеся следствием молодости (т.е. процесса активной разработки и не до конца установившимися концепциями) языка. Однако говорить о недостаточной кроссплатформенности Rust довольно смешно, т.к. там в роли бэкенда работает llvm (предлагаю посмотреть на список доступных платформ).
А… ну ладно тогда, а то вы тут было впали в какую-то блаженную эйфорию, 150 классов и т.д. :)
150 классов типа perfromer точно так же никак и один такой класса нисколько не изменят производительность данного теста.
Глупо спорить, тут надо проверять. Но мне, естественно, лень будет гонять два варианта, поэтому в релиз может войти только версия с полным набором классов
Ну кому-то возможно и надо проверять, а кому-то достаточно знаний о работе компиляторов C++… )))
HelloWord в Qt, в дефолтном Release будет весить около 10Кб (динамическая линковка).
Ни в Nim-е, ни в Rust-е у вас даже близко не будет ни с динамической линковской, ни тем более в дефолтной конфигурации.
Ну а теперь посмотрим на реальность… Для примера возьмём скомпилированные для windows 64 бита приложения «hello world»:
Я думаю из этих данных вполне очевидно преимущество статической линковки над динамической (конечно при условии, что у нас в итоговом приложение один exe файл), а так же реальная жирность Java и Qt решения.
Т.е. очень много вспомогательного кода попадает в бинарь и, например, при любых исправлениях/обновлениях в системных функциях языка вам нужно будет перебилживать приложение.
Все это плохо, и это мое мнение.
Вот бредовость этого мнения тут и обсуждается. Оно неверно потому, что даже если уж и принимать в расчёт занимаемое на диске место (хотя в наше время больших дисков и быстрого интернета это всё давно стало неактуальным), то это должен быть размер дистрибутива приложения, а не размер исполняемого файла.
Но, как я уже неоднократно писал, языки эти отсеялись по многим другим факторам, а совсем не только по размеру бинаря.
Никаких других внятных причин я в статье не увидел.
Классы в C++ это вполне реальные, а не эфемерные сущности, они создаются, удаляются, для них вызываются конструкторы/деструкторы/методы. На все это тратится вполне конкретное машинное время, и компилятор далеко не всегда сможет выполнить эффективную оптимизацию.
Когда классы уже скомпилированы и положены, например, в динамическую библиотеку никакой оптимизации при использовании этой библиотеки (во время компиляции приложения) в вашем приложении уже не будет.
Мы обсуждаем не абстрактный код в вакууме, а вполне конкретный тестовый пример. И моё конкретное утверждение о том, что если добавить в мою реализацию этого теста никчемные классы dcf_file и perfomer (остальные классы у меня присутствуют аналогично решению из статьи), то время исполнения теста не изменится. Есть желание оспорить это утверждение? )))
Если классы в статической библиотеке, то в общем случае тоже, разве что вы не пользуетесь компилятором от Intel с включенным IPO.
Вообще то это доступно во всех известных компилятора уже несколько десятилетий. ))) Только в остальных это называется LTO.
Что-то статья напоминает какое-то маркетинговое впаривание, а не технический материал. Защитные лаки для покрытия печатных плат известны уже очень давно и сейчас продаются в каждом профильном магазине…
Недостаток оптимизации по размеру файла вполне себе аргумент, не знал что это фобия :)
Если сравнивать статически скомпонованные нативные исполняемые файлы, то да, это нормально. К примеру если для решения одной и той же задачи статически скомпонованное приложение на C++ занимает 1 МБ, а на C++/Qt 7 MB, то вполне могут возникнуть вопросы об оптимизации Qt по данному вопросу. Однако если начинать сравнивать ещё и динамическую компоновку, причём беря в расчёт исключительно размер исполняемого файла (и наплевать, что рядом с ним валяется dll в 100 раз большего размера), то это уже становится чем-то из области психиатрии…
Это была большая небрежность с моей стороны, признаю, но в конце концов я именно для этого и выложил исходники чтобы все могли посмотреть и указать на ошибки.
И статья и исходный код отлично гармонируют между собой по наличию ошибок. Однако если относительно исходного кода вы их признаёте, то относительно самой статьи почему-то аналогичных выводов нет…
Да и не надо утруждаться :) все равно это не годится. Смысл был в том чтобы на всех языках иметь одинаковую структуру приложения и классов. Чтобы затраты на создание и уничтожение классов тоже учитывались. Но за старания спасибо :)
Хы, это же C++, язык основной концепций которого является нулевая цена абстракций. Можно навернуть там ещё хоть 150 классов типа Perfomer и от этого не только не поменяется производительность, но и даже не поменяется сам код (с точностью до бита) — компилятор просто выкидывает все эти лишние уровни абстракции в процессе оптимизации.
Ну и да, в любом случае не стоит применять архитектуру приложения происходящую из языков с навязанным ООП (типа Java, C# и т.п.) к полноценным мультипарадигменным языкам. Тем более, что современный C++ всё больше уходит от ООП в сторону функциональных стилей и т.п.
Исполняемый файл будет больше чем jar, но зато в нем будут все «кишки» языка :) если прибавить рантайм Java то он будет весить больше.
Вам самому-то не надоело это муслоить? :) Вроде бы очевидные вещи.
Если это действительно очевидные вещи, то тогда солидный кусок обсуждаемой статьи надо бы выкинуть… )))
Совершенно не хочется пересказывать ту часть статьи другими словами — кратко «жирные» бинари на мой взгляд это не эстетично, думаю тут есть простор для оптимизации, не более того.
Это уже не инженерные аргументы, а какие-то личные фобии.
Думаю что JVM портирован на большее количество платформ чем тот же Nim и Rust — это кроссплатформенность. Да и со стабильностью в JVM все будет почетче.
Вообще то Nim компилируется в C++ (который априори более кроссплатформенный, чем любые обсуждаемые тут языки). А что касается Rust'а, то например это второй язык (после C++), который имеет возможность написания кода для платформы WebAssembly (будущее нагруженного web'a), что является недостижимым для JVM в данный момент.
Спорное утверждение, дизайн проверенный временем доказал свое право на существование.
Любители Кобола говорили также… )))
Отлично, код в студию! :)
Сейчас будет, но перед этим хочу заметить, что из-за создания своего варианта, я более внимательно посмотрел на представленные и заметил откровенные махинации. Странно что никто больше их не заметил. А именно, у класса DcfSegment (именно его экземпляры создаются миллионами в тесте) в Java реализации имеется функция getLength(), которая вычисляет длину сегмента при своём вызове (т.е. никогда в данном тесте) на базе значений конечных точек. В тоже время аналогичная функция из класса DcfSegment в C++ реализации возвращает значение поля mLength (которого вообще нет в Java реализации), которое вычисляется в конструкторе класса. Т.е. в C++ варианте не только имеем лишнее поле, но и дополнительные тяжёлые вычисления при каждом конструирование такого объекта. И это называется тестом производительности? Скорее похоже на откровенную махинацию…
Ну а что касается варианта на современном C++, то выкладывать весь проектик на какие-то ресурсы мне лень, так что кину исходник прямо в этом комментарии (обрезав инклуды с неймспейсами, чтобы покомпактнее было):
Только посмотрел так сказать для общего развития. С самим этим языком я раньше дел не имел, так что ни запускать, ни проверять уровень кода особой возможности не имею.
Кстати, как раз благодаря просмотру кода на разных языках неожиданно (изначально я этого не заметил) оказалось, что автор статьи ещё и смухлевал немного — код разный (принципиально, а не из-за особенности языка) на разных языках. Детали опишу в другом комментарии (ниже).
Во-первых, JVM бывают разные, есть очень маленькие.
Меньше получаемого в Rust/D/Nim исполняемого файла под той же платформой? )
В-третьих, JVM портирован почти везде, так что можно считать его частью системы.
Похоже кто-то тут путает кроссплатформенность (имеется не только у JVM, а много где, включая и Rust/D/Nim) и предустановленный в данной ОС рантайм. Я что-то не слышал про предустановленный рантайм Java на Windows или OSX или Linux…
Раз уж это моя статья позвольте мне и решать кого записывать в перспективные. Напишите свою — с удовольствием почитаю.
Выбирать критерии отбора языков — это безусловно авторское дело. Однако, даже если использовать для этого такой странный по нынешним временам (если конечно речь не про МК) параметр, как размер получаемого дистрибутива, то всё равно это надо делать честно (учитывая весь рантайм). Именно это один из главных недостатков статьи, просто бросающийся в глаза своей некорректностью.
На мой взгляд, красота и удобство Qt API в сравнении с убогой std в разы перевешивают возможные потери производительности.
Ха, совсем неудивительна симпатия Java-программиста к Qt. Только вот надо понимать, что это совсем не путь развития современного C++. Qt родилась в 90-ые (как раз одновременно с Java) и вся её архитектура из тех времён. Сейчас мир C++ уже далеко ушёл от этого в совсем другую сторону и данный Java-стиль является откровенным legacy. Конечно авторы Qt понемногу пытаются исправить эту ситуацию, но пока выходит очень слабо.
Да нет там никакого «Java стиля» обычный Qt-шный код.
)))
Код в студию, пожалуйста, только не в С-style.
Накидал сейчас для развлечения на нормальном C++ (с Boost'ом вместо Qt) программку с полностью аналогичной функциональностью. Значит получился один файл исходников из 70 строк/2,4 КБ, причём 1/3 файла занимают подключения заголовочных файлов и пространств имён. Исполняемый файл при полной (включая стандартную библиотеку языка, т.е. такой exe можно спокойно распространять везде в одиночку) статической линковке на 64-ёх битной Windows занимает 1 МБ. Время работы в 1,5 раза меньше, чем у приведённого в статье Java кода, что в общем то и ожидалось изначально.
Мда… Мне ещё не приходилось писать столько отрицательных комментариев, к статье с вроде как правильной изначальной идеей — такого уникально низкого уровня реализации я давно не видел.
Для начала сразу же повеселила фраза «Т.е. маленькая програмулька, которая печатает в консоль тупую строчку и должна занимать от силы 3-4Кб весит мегабайты!» Ну так оно и весит мегабайты на практически всех языках, кроме разве что чистого C++. В той же Java это будет более 100 мегабайт (мы же будем по честному считать, включая рантайм, не так ли?). Причём эта фраза была в статье не просто так, а на её основание из тестирование убрали как раз самые интересные и перспективные языки.
На фоне предыдущего пункта меня сильно поразило наличие в тестирование C++/Qt, т.к. как раз Qt и является примером очень жирной библиотеки — тут было явно что-то не то. Но когда я увидел размер программы на Qt в 37 КБ, то всё стало на свои слова — автор похоже ещё и не особо разбирается в разнице между статической и динамической линковкой…
Так же слегка шокировали слова «обычные язык, без откровений» по отношению к Scala. И это про язык, который принёс полноценное функциональное программирование и метапрограммирование в мир JVM.
После всего этого на результаты тестов уже можно было и не смотреть особо… Гораздо интереснее было взглянуть на исходники. И в первую очередь на вариант с C++. Собственно как и ожидалось, там был классический «java стиль», тот самый, который не позволяет писать быстродействующее ПО на C++. Если же решить эту простейшую задачку на нормальном современном C++ (и для начала это будет Boost, а не Qt), то она будет и в разы быстрее и в разы меньше кода.
В итоге статье крайне не понравилась огромным числом ляпов, не говоря уже о смешных итоговых результатах.
А вот действительно принципиальным отличием является тот факт, что данная библиотека отрабатывает на этапе компиляции (она построена с помощью метапрограммирования), а не исполнения. Т.е. если записывать какие-то формулы физических расчётов в C++ коде, то компилятор просто не даст собраться программе с неверное (с точки зрения единиц измерения) формулой.
Это да. Но это потому что собственно в технической (научной, инженерной и т.п.) практике такое обычно не используют, вне зависимости от системы единиц. Т.е. если у нас есть допустим 1,5*10^3 м, то мы можем это красиво записать как «1500 метров» или «1,5 километра», но не как «1 километр 500 метров».
Что касается конкретных реализаций, то их тоже бывает множество, в зависимости от возможностей языка. Есть как наивные рантаймовые реализации через enum (в языках типа C), так и реализации через систему типов, как например здесь www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/index.html. Более того, использование элементов метапрограммирования позволяет задавать эти самые зависимости между типами в таком www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/ch03s04.html#d0e1462 удобном виде.
Так что автор конечно же мыслит в правильном направление, но мне кажется не до конца изучил уже существующие в данный момент наработки.
И да, у Rust'а имеется ряд преимуществ над C++. Это и более строгая работа с памятью и нормальное метапрограммирование (а не корявые вычисления на шаблонах) и т.п. Но про это в статье нет ни одного слова…
Но вот пример для mock какой-то странный. Если уж мы там выделили в тестируемом коде работу с веб-сервисом в отдельную функцию (LogError), то никакие IWebService нам уже не требуются, т.к. мы можем банально завести переменную lastError и писать в неё прямо в классе TestingEntryAnalyzer.
Понятно, что это всё демонстрационные примеры для статьи. Но они всё же в них должен быть логический смысл — если используем mock, то должна быть видна потребность в таком решение.
Вот как раз с такими и игрался. Советую попробовать не обновлять подобный дистрибутив 1-2 года и потом запустить обновление…
В Windows как раз не особо употребляется совместное использование динамических библиотек. В системый каталог кладётся только их малое число, а большинство устанавливается в каталог приложения. Так что под Windows у каждого приложения используется своя версия (и на одном компьютере их может быть множество). Хотя и там изредка бывают проблемы из этой области (обычно когда сомнительное ПО прописывает себя в path), но гораздо реже… Только вот это следствие не умной системы зависимостей, а наоборот уход от неё. Точно так же как и на OSX.
Вот что меня действительно поражает, так это ваше полное игнорирование оценок статьи, а так же этой беседы в комментариях — у вменяемого человека хотя бы из-за них возможно закрались бы какие-то сомнения в собственно правоте. Но у вас ни малейших не появилось. Но вы правы в одном: действительно пора заканчивать — мне уже наскучило стучаться в эту стену…
И что же это интересно за толково созданные системы, в которых нормально работает модульность? Надеюсь речь не про Линух, который не раз дох у меня полностью от банального обновления…
В статье на основание не верного представления автора о вопросах компоновки (чего только стоит сравнение размеров исполняемого файла при разных компоновках) делаются вполне однозначные выводы о выборе языков программирования…
Что-то похоже у кого-то в голове путаница между пользователями, админами и разработчиками. Нормальные пользователи не то что не занимаются подобным, они даже не поймут о чём речь.
Для C++ это вообще не работает, т.к. там большая часть кода (включая unordered_map) является шаблонами.
Хм, что за глупости? Рантайм там даже меньше чем у C++ выходит. И со стабильностью тоже всё хорошо — язык уже устоялся, в отличие от Rust.
Собственно там и gcc есть gdcproject.org )))
Это всё какие-то эксперименты, официальным решением для D является компилятор dmd. И у него со стабильностью всё отлично.
О, очередное шедевральное высказывание в дополнение к статье… Конечно же зачем нам статическая компоновка, если в ней нет ни замедления работы, ни раздувания дистрибутива, и главное в ней нельзя насладится такой очаровательной вещью, характерной для динамической компоновки, как dll hell.
Осталось только уточнить одну «мелочь»: кому и зачем это вообще надо? )))
Что-то не увидел описания причин выбывания языка D.
Что касается Rust'а, то ему действительно можно предъявить определённые претензии, являющиеся следствием молодости (т.е. процесса активной разработки и не до конца установившимися концепциями) языка. Однако говорить о недостаточной кроссплатформенности Rust довольно смешно, т.к. там в роли бэкенда работает llvm (предлагаю посмотреть на список доступных платформ).
150 классов типа perfromer точно так же никак и один такой класса нисколько не изменят производительность данного теста.
Ну кому-то возможно и надо проверять, а кому-то достаточно знаний о работе компиляторов C++… )))
Ну а теперь посмотрим на реальность… Для примера возьмём скомпилированные для windows 64 бита приложения «hello world»:
C++ static: 832 KБ (exe) + 0 KБ (dll) = 832 KБ
C++ dynamic: 16,5 KБ (exe) + 1510,5 KБ (dll) = 1527 KБ
C++/Qt static: 4109 KБ (exe) + 0 KБ (dll) = 4109 KБ
C++/Qt dynamic: 17 KБ (exe) + 7378 KБ (dll) = 7395 KБ
D static: 565 KБ (exe) + 0 KБ (dll) = 565 KБ
Rust static: 2305 KБ (exe) + 0 KБ (dll) = 2305 KБ
Java dynamic: 0,4 КБ (class) + 158418,6 КБ (jre) = 158419 КБ
Я думаю из этих данных вполне очевидно преимущество статической линковки над динамической (конечно при условии, что у нас в итоговом приложение один exe файл), а так же реальная жирность Java и Qt решения.
Вот бредовость этого мнения тут и обсуждается. Оно неверно потому, что даже если уж и принимать в расчёт занимаемое на диске место (хотя в наше время больших дисков и быстрого интернета это всё давно стало неактуальным), то это должен быть размер дистрибутива приложения, а не размер исполняемого файла.
Никаких других внятных причин я в статье не увидел.
Мы обсуждаем не абстрактный код в вакууме, а вполне конкретный тестовый пример. И моё конкретное утверждение о том, что если добавить в мою реализацию этого теста никчемные классы dcf_file и perfomer (остальные классы у меня присутствуют аналогично решению из статьи), то время исполнения теста не изменится. Есть желание оспорить это утверждение? )))
Вообще то это доступно во всех известных компилятора уже несколько десятилетий. ))) Только в остальных это называется LTO.
Если сравнивать статически скомпонованные нативные исполняемые файлы, то да, это нормально. К примеру если для решения одной и той же задачи статически скомпонованное приложение на C++ занимает 1 МБ, а на C++/Qt 7 MB, то вполне могут возникнуть вопросы об оптимизации Qt по данному вопросу. Однако если начинать сравнивать ещё и динамическую компоновку, причём беря в расчёт исключительно размер исполняемого файла (и наплевать, что рядом с ним валяется dll в 100 раз большего размера), то это уже становится чем-то из области психиатрии…
И статья и исходный код отлично гармонируют между собой по наличию ошибок. Однако если относительно исходного кода вы их признаёте, то относительно самой статьи почему-то аналогичных выводов нет…
Хы, это же C++, язык основной концепций которого является нулевая цена абстракций. Можно навернуть там ещё хоть 150 классов типа Perfomer и от этого не только не поменяется производительность, но и даже не поменяется сам код (с точностью до бита) — компилятор просто выкидывает все эти лишние уровни абстракции в процессе оптимизации.
Ну и да, в любом случае не стоит применять архитектуру приложения происходящую из языков с навязанным ООП (типа Java, C# и т.п.) к полноценным мультипарадигменным языкам. Тем более, что современный C++ всё больше уходит от ООП в сторону функциональных стилей и т.п.
Если это действительно очевидные вещи, то тогда солидный кусок обсуждаемой статьи надо бы выкинуть… )))
Это уже не инженерные аргументы, а какие-то личные фобии.
Вообще то Nim компилируется в C++ (который априори более кроссплатформенный, чем любые обсуждаемые тут языки). А что касается Rust'а, то например это второй язык (после C++), который имеет возможность написания кода для платформы WebAssembly (будущее нагруженного web'a), что является недостижимым для JVM в данный момент.
Любители Кобола говорили также… )))
Сейчас будет, но перед этим хочу заметить, что из-за создания своего варианта, я более внимательно посмотрел на представленные и заметил откровенные махинации. Странно что никто больше их не заметил. А именно, у класса DcfSegment (именно его экземпляры создаются миллионами в тесте) в Java реализации имеется функция getLength(), которая вычисляет длину сегмента при своём вызове (т.е. никогда в данном тесте) на базе значений конечных точек. В тоже время аналогичная функция из класса DcfSegment в C++ реализации возвращает значение поля mLength (которого вообще нет в Java реализации), которое вычисляется в конструкторе класса. Т.е. в C++ варианте не только имеем лишнее поле, но и дополнительные тяжёлые вычисления при каждом конструирование такого объекта. И это называется тестом производительности? Скорее похоже на откровенную махинацию…
Ну а что касается варианта на современном C++, то выкладывать весь проектик на какие-то ресурсы мне лень, так что кину исходник прямо в этом комментарии (обрезав инклуды с неймспейсами, чтобы покомпактнее было):
Кстати, как раз благодаря просмотру кода на разных языках неожиданно (изначально я этого не заметил) оказалось, что автор статьи ещё и смухлевал немного — код разный (принципиально, а не из-за особенности языка) на разных языках. Детали опишу в другом комментарии (ниже).
Меньше получаемого в Rust/D/Nim исполняемого файла под той же платформой? )
Похоже кто-то тут путает кроссплатформенность (имеется не только у JVM, а много где, включая и Rust/D/Nim) и предустановленный в данной ОС рантайм. Я что-то не слышал про предустановленный рантайм Java на Windows или OSX или Linux…
Выбирать критерии отбора языков — это безусловно авторское дело. Однако, даже если использовать для этого такой странный по нынешним временам (если конечно речь не про МК) параметр, как размер получаемого дистрибутива, то всё равно это надо делать честно (учитывая весь рантайм). Именно это один из главных недостатков статьи, просто бросающийся в глаза своей некорректностью.
Ха, совсем неудивительна симпатия Java-программиста к Qt. Только вот надо понимать, что это совсем не путь развития современного C++. Qt родилась в 90-ые (как раз одновременно с Java) и вся её архитектура из тех времён. Сейчас мир C++ уже далеко ушёл от этого в совсем другую сторону и данный Java-стиль является откровенным legacy. Конечно авторы Qt понемногу пытаются исправить эту ситуацию, но пока выходит очень слабо.
)))
Накидал сейчас для развлечения на нормальном C++ (с Boost'ом вместо Qt) программку с полностью аналогичной функциональностью. Значит получился один файл исходников из 70 строк/2,4 КБ, причём 1/3 файла занимают подключения заголовочных файлов и пространств имён. Исполняемый файл при полной (включая стандартную библиотеку языка, т.е. такой exe можно спокойно распространять везде в одиночку) статической линковке на 64-ёх битной Windows занимает 1 МБ. Время работы в 1,5 раза меньше, чем у приведённого в статье Java кода, что в общем то и ожидалось изначально.
Для начала сразу же повеселила фраза «Т.е. маленькая програмулька, которая печатает в консоль тупую строчку и должна занимать от силы 3-4Кб весит мегабайты!» Ну так оно и весит мегабайты на практически всех языках, кроме разве что чистого C++. В той же Java это будет более 100 мегабайт (мы же будем по честному считать, включая рантайм, не так ли?). Причём эта фраза была в статье не просто так, а на её основание из тестирование убрали как раз самые интересные и перспективные языки.
На фоне предыдущего пункта меня сильно поразило наличие в тестирование C++/Qt, т.к. как раз Qt и является примером очень жирной библиотеки — тут было явно что-то не то. Но когда я увидел размер программы на Qt в 37 КБ, то всё стало на свои слова — автор похоже ещё и не особо разбирается в разнице между статической и динамической линковкой…
Так же слегка шокировали слова «обычные язык, без откровений» по отношению к Scala. И это про язык, который принёс полноценное функциональное программирование и метапрограммирование в мир JVM.
После всего этого на результаты тестов уже можно было и не смотреть особо… Гораздо интереснее было взглянуть на исходники. И в первую очередь на вариант с C++. Собственно как и ожидалось, там был классический «java стиль», тот самый, который не позволяет писать быстродействующее ПО на C++. Если же решить эту простейшую задачку на нормальном современном C++ (и для начала это будет Boost, а не Qt), то она будет и в разы быстрее и в разы меньше кода.
В итоге статье крайне не понравилась огромным числом ляпов, не говоря уже о смешных итоговых результатах.