Комментарии 129
Ну так вот, при этом код на С++ оказался впереди на считанные проценты времени. Выигрыш был бы съеден дополнительными расходами на вызов через JNI, поэтому от переноса мы решили отказаться. Это был код который делает много вычислений, но особо не аллоцирует память и в целом в С++ переносится практически один-в-один.
Так что именно перемалывание циферок у них примерно одинаково. За счет «оптимистичных оптимизаций», приведенных в статье, джава может даже вырываться вперед иногда.
Т.е., допустим, я не могу накопить массив байтов и потом конвертировать его в строку без копирования.А как вы это в C++ сделаете?
В то же время на c/c++/rust подоных копирований можно избежать не теряя читабельность кода и не изобретая свои велосипеды под конкретные случаи.Я боюсь что «без велосипедов» не получится. Другое дело, что стиль написания с передачей фрагментов буфера туда-сюда в Java выглядит как-то что исключительно кривое и, скажем так, инородное. А в C++ — это один из типичных стилей написания программ. Но это скорее вопросы культуры и стиля.
Проблема Java в том, что весь этот код, из которого JIT'ы умеют делать «конфетку» — он нифига не идеоматичен. А идеоматичный код (со всякими фабриками фабрик фабрик, DI через отражение или, что ещё «круче», через XML-конфиг) ни один JIT вам ни во что вменяемое не превратит…
В области обработки изображений для алгоритмов характерен высокий параллелизм и не требуется, как правило, высокая точность (что позволяет часто использовать в вычислениях числа с фиксированной точностью). Эти характеристики позволяют в большинстве случаев очень эффективно задействовать SIMD, которые сейчас поддерживают практически все современные процессоры. Так вот задействование SIMD позволяет в среднем получить дополнительный выигрыш на порядок. С++ позволяет эффективно задействовать SIMD при помощи интринсиков. Как с этим у Java?
А так да, я сам лично проводил сравнение кода (без SIMD оптимизаций) на С++ и C# — и еще лет 6 назад выигрыш С++ не превышал 30%, что делало не актуальным простое переписывание кода из managed языков на С++).
Насколько я знаю, HotSpot JIT может применить SIMD, но на довольно ограниченном наборе паттернов.
Ещё раз спасибо за статью :) Ну и по теме.
Я, таки, попробовал на ArrayList'e из одного / двух элементов — там таких эффективных оптицизаций нет.
За то если параметр заменить на String[] — testIterator(String[] array) и передавать туда new String[] { «abc» }, то он вообще схлопывается в константу «3», а внешний цикл на 1 000 000 итераций анроллится (хотя я техническое дно в ASM и могу ошибаться).
Опять же на C++ в сравнении с C# в рамках платформы без доступа к unsafe можно не слабо сэкономить на работе с массивами.
Я при переходе с C# на C++ для расчета данных треков, выиграл чуть больше чем в два раза, правда после перехода на DXMath, который перенес математику на SSE и Neon, выигрыш стал намного более значительным.
Например, https://www.techempower.com/benchmarks. Java там стабильно в лидерах.
Даже прочитав эту статью у меня возникает недоумение: фраза «Этим JIT отличается от приложений скомпилированных заранее: исполняемый машинный код вашей программы может меняться, следуя за изменениями в её поведении.» подразумевает, что JIT чем-то лучше… но постойте… В приложении, скомпилированном заранее, в процессе работы выполняется только приложение. В случае же с JIT — параллельно работает ещё и компилятор, который к тому же собирает статистику! Даже если приложение за счёт адаптации к изменениям в поведении станет работать быстрее — работа компилятора всё равно съест весь прирост.
Компилятор много работает на старте приложения. Через несколько минут интенсивной работы доля CPU, съедаемая компилятором, уже невелика. Кроме того редко когда у вас все ядра загружены, а компилятор асинхронно работает.
К слову, на рабочем компе не редка ситуация «Загружены все ядра», ибо компьютер там слабый. По странному стечению обстоятельств, эта ситуация почему-то совпадает с отладкой java-приложений в IDE, написаном на java.
Я нисколько не умаляю достоинств JIT — я охотно вам верю, что если бы не он — java тормозила бы на порядок больше. И того, что использовани java зачастую оправдано — я тоже не отрицаю. Но, будем честны, быстродействие — это не сильная сторона java.
PS да, разработка на java требует компьютера посерьёзней, чем простой офисный. И по памяти и по мощности cpu желателен буст. Впрочем всё это нужно для ускорения разработки, которая и без того зачасту быстрее разработки программ на c++.
PPS я знаю, что теоретически из c++ можно выжать много больше, знаю, что на некоторых классах задач он будет рвать java как тузик грелку. Вообще c++ выбран как пример языка, программы на котором очень часто сравнивают по производительности с программами на java.
быстродействие Java на многих классах задач сравнима (чуть хуже/чуть лучше) с производительностью, получаемой на c++?Нельзя сравнивать «быстродействие на многих классах задач». Можно сравнивать «определённым способом написанный код».
Всё упирается в один простой факт: работа с таким массивом
struct {
int x;
int y;
} array1[100];
в несколько раз быстрее, чем с такимstruct {
int x;
int y;
} (*array2)[100];
И всё что делает JIT — пытается всеми правдами и неправдами превратить
array2
в array1
.К огромному сожалению для людей, вынужденных пользоваться программами на Java весь язык, все библиотеки и вообще вся экосистема построены на превращении из
array1
в array2
. Многократном и повсеместном. Никакой JIT тут не спасёт.А главное — в программах где
array1
доминирует всё ради чего затеяны все сложности, которые героически решают разработчики JIT'ов не нужны. Если нет бесконечных уровней индирекции и запутанных иерархий абстракий, то не так сложно отследить — кто чем владеет, а значит не нужен GC. Раз не нужен GC и типы заранее известны — то все навороты типа «est %eax,-0x27b759f(%rip)» — тоже не нужны. И так далее.Вообще c++ выбран как пример языка, программы на котором очень часто сравнивают по производительности с программами на java.И всё всегда сводится к одному вопросу: а почему, собственно, если JIT так крут — то почему все программы на Java тормозят? А если программы всё равно тормозят — то о какой «крутости» вы тут говорите?
И обе стороны по своему правы. А истина — посередине: JIT-компиляторы, несомненно, круты, но проблема в том, что они, по большей части, решают задачу которой вообще не должно было быть!
все программы на Java тормозят
Список можно? А то уже несколько людей говорят, что всё на java у них тормозит, но почти ни одного названия тормозящих программ нет. Ну и ещё конфигурацию компа, на котором всё это тормозит.
А то у меня на рабочем компе вполне могут работать 2 экземпляра IDE, запущен хром и фф. Ничего из этого не тормозит, хотя конфигурация далеко не топовая.
Вам перечислить список всех существующих программ на java?
Нет, хотел увидеть список программ, которыми вы реально пользовались и которые тормозили при этом.
А вы можете дать список программ на java, которые не тормозят?
Могу назвать те, которыми пользуюсь я.
Например, IDE от JetBrains. После запуска, построения индекса и загрузки кэша работают шустро.
Ещё при работающей IDE только что запустил 2 профайлера (JProfiler и YourKit Java Profiler). Каждый из них работал без тормозов: интерфейс отзывчивый, фризов не наблюдал.
Больше я особо не припомню java-приложений, которыми пользуюсь. А называть всё подряд и говорить "не тормозит" я не буду. Но если уж такие программы работают шустро, то и более мелкие не должны тормозить.
PS Запустил SweetHome 3D для проверки. Работал без тормозов, но я особо не добавлял объектов, так что точно не могу сказать.
Система: linux, oracle vm 64bit, 8GB RAM, Core i5 2.2GHz.
Сталкивался с одним коллегой, который говорил, что его демо прога на C# работает быстрее чем на Java. Суть была в плавной смене цветов в квадратах (на форме девять квадратов) и якобы на Java это медленнее. В ходе разбора выяснилось, что просто на Java он кривой код написал — переписали и визуальной разницы перестали замечать.
Вывод: тормозит не JVM, а кривой код на ней
И люди видят, что программы на java работают медленно
А какие программы? Просто чтобы сравнивать более объективно, нужно брать продукты примерно одного уровня с идентичными возможностями на разных языках.
У меня, например, из десктопных java-программ есть только IDE (Idea). Ну да, они тормозят. Точно так же, как и IDE на C++ (Visual Studio). Да и то, тормоза в идеи в основном только при индексации проекта.
Ещё любят упоминать Minecraft как пример тормозной java-программы. Там тормоза связаны с недостаточной оптимизацией самой игры (по крайней мере, Нотч не особо оптимизировал, как сейчас там дела я не знаю). Ну и тормозило там всё в основном при генерации новых чанков, что вполне понятно. Ну и опять же, как будто подобные игры на C++ не тормозят.
Так может программы на java тормозят не потому что на java, а потому что они просто либо очень сложные, либо плохо оптимизированны, а язык и платформа тут не вносят существенных тормозов?
P.S. Моё мнение обо всём этом managed безумии сложилось во времена WRT.EXE из Borland C++ 2.0. Который нещадно тормозил и требовал «невероятных» (по тем временам) ресурсов (при отвратительной функциональности, надо сказать). Через год вышел Borland Resource Workshop и про тормоза все забыли. Вспомнили когда началась вся эта истерия вокруг Java — и до сих пор слышим мантры про то, какой крутой Java JIT и что тормоза — это фигня, главное — функцинальность. Увы, но тормозят C# и Java всегда, а функциональность… — может быть, может не быть…
Многие распространенные мифы про тормознутость Java строятся на (не совсем корректных) прикидках.
Ну вот давайте и прикинем. Известно что узкое место в работе (нормального) компьютера это доступ в память. Разработчику не жалко потратить десятки а иногда сотни тактов процессора чтобы избежать лишнего доступа в кеши процессора или в оперативку. 90% времени процессор пользовательского компа простаивает в ожидании подгрузки чего-нибудь из памяти.
Когда загружается программа на C, это более-менее полотно ассемблерных инструкций для всех возможных веток выполнения программы. Вроде понятно.
Когда загружается Java программы, она состоит из JVM байт-кода и интерпретатора JIT. А теперь фокус: байткод и интерпретатор зачастую вместе занимают меньше места чем соответствующий ассемблер. Этим экономится драгоценное место в памяти и кешах. Достигается это тем что JVM байт-код это хорошо упакованные высокоуровневые инструкции, которым могут соответствовать десятки команд ассемблера.
Вот так и получается что действия, которые выполняются относительно редко (95% всей логики), логично интерпретировать. Действия которые выполняются часто и влияют на производительность «распаковывают» из байт-кода в машинные команды различной степени оптимальности.
Когда Вы запускаете IDE вроде IntelijIdea, 5 минут в начале она подтормаживает, происходит тот самый «прогрев» — инициализация и распаковка кода. После этого она начинает ускорятся, и через полчаса летает (это мои собственные ощущения). Готов поспорить что если гипотетически скомпилировать ее в машинные команды (реально не получится ибо рефлекшн), то эти 5-20 минут разогрева потратятся просто на загрузку разбухшего кода в память и прогрев кешей.
Ну и в «и интерпретатор зачастую вместе занимают меньше места чем соответствующий ассемблер.» мне как-то верится с трудом. К сожалению, полноценно это утверждение проверить не удастся, ибо это будет либо компиляция каких-то синтетических тестов, либо и вовсе несравнимые вещи.
Я не берусь делать выводы о причинах — возможно, это просто нерепрезентативная выборка, и мне не везло, возможно — это недостаток хороших программистов, пишущих на java, из-за низкого уровня вхождения в язык, возможно — это таки следствие реально более низкого быстродействия. А может быть, тут совокупность всех этих факторов, это мне кажется наиболее вероятным.Причина, конечно, не в JIT'е. Прична — в том, что изначально вся архитектура Java'ы сделана так, что железу исполнять программы не просто трудно, а черезвычайно трудно. Как известно все проблемы в информатике можно решить с помощью дополнительного уровня абстракции… за исключением проблемы слишком большого количества абстакций. А проблемы со скоростью и излишним потреблением памяти — это и есть проблемы слишком большого количества абстракций в 99 случаях из 100.
За то время пока вы сходите в память разименовать один указатель процессор успеет обратить матрицу 10x10… или отсортировать массив на 100 элементов… или ещё что-нибудь подобное посчитать. А у вас тут фабрики фабрик фабрик, DI и отражения… которые все, что характерно, построены на бесконечных индирекциях…
Можно ли написать на Java код так, чтобы он был быстрее, чем код на C/C++? Да, разумеется. Но для этого вам потребуется программист с опытом работы на FORTRAN или C++, а не Java. А такому программсту, представьте себе, проще и удобнее писать на FORTRAN или C++!
я говорю «программа тормозит весь компьютер»
Допустим, в системе запущен браузер, ещё пара мелких приложений. Всё это дело потребляет 3Гб из 4-х. Всё работает без тормозов. Я запускаю IDE, памяти не хватает, всё начинает жутко лагать. Кажется, что ИДЕ затормозила всю систему…
Теперь другая ситуация: запущена IDE, пара мелких приложений. Память не израсходована до конца, всё летает. Я открываю в браузере кучу вкладок, память кончается, всё тормозит. Кто теперь виноват в тормозах?
Тут не IDE тормозит всю систему, и не браузер, а совокупность факторов. Лично по моему опыту, всё начинает тормозить, когда память подходит к концу. Да, зачастую java-приложения довольно прожорливы в плане памяти.
Ещё есть такой момент: количество потребляемой памяти для java-программы можно ограничить через JVM. Если программа по какой-то причине не укладывается в кол-во выделенной ей памяти — она обычно начинает тормозить. А вот кол-во памяти потребляемой программой на C++ ограничить уже не так просто. Она может отъесть очень много ОЗУ. В таком случае может просто случиться так, что JVM не сможет выделить много памяти приложению, и оно будет тупить, при этом всё остальное тормозить не будет.
Кстати, можете привести пример java-программ для десктопа, которые у вас тормозили? Просто я кроме IDE и сопутствующих утилит особо не запускал. И IDE у меня тормозит только при запуске/индексации. Ну или когда вся память закончилась (но тогда тормозит всё, и дело тут уже не в java).
Ещё есть такой момент: количество потребляемой памяти для java-программы можно ограничить через JVM.Нельзя, не рассказывайте сказок. Можно ограничить количество памяти, которое JVM будет сжирать без всякой причины.
А вот кол-во памяти потребляемой программой на C++ ограничить уже не так просто.ulimit кто-то отменил? Только в случае с C++ — это «ремень безопасности», грамотно написанная программа на C++ не должна потреблять лишней памяти (и не делает этого на практике). Только не надо про браузеры — современные браузеры, увы, это не «просмотрщики гипертекста», как они задумывались, а интерпретаторы-переростки для языка, который пытается доказать, что Java — это всего лишь «ужас», а не «ужас-ужас».
Кстати, можете привести пример java-программ для десктопа, которые у вас тормозили?Тормозит всё, что я запускал. IDEA, Vuze, даже какие-нибудь мелкие утилитки типа Keypass'а (это, правда, C# — но принцип тот же).
Разумеется у меня на десктопе (64GiB RAM, Dual Xeon, 24 ядра, 48 потоков) — проблем нет. Но стоит мне пересесть на «печатную машинку» моей сестры (2GiB RAM, Atom) — всё, можно умереть.
Только не надо про «ну чего вы хотите от такой системы»: я хочу чтоб работало. И если для программы на C/C++ мне нужна машинка за $100, а для программы на Java для получения одинакового «фана и экспиреенса» — за $10'000, то это, у нормальных людей, не обременённых глубокими познаниями в IT, и называется «тормозит».
грамотно написанная программа на C++ не должна потреблять лишней памяти (и не делает этого на практике)
Как и на любом другом языке.
Тормозит всё, что я запускал. IDEA, Vuze
Ну вот, наконец-то назвали вторую тормозящую программу. Конкретно про Vuze не могу ничего сказать. (помню только, что это большой комбайн, включающий в себя кучу всего нужного и не очень).
А вот про идею...
(2GiB RAM, Atom)
я хочу чтоб работало
И если для программы на C/C++ мне нужна машинка за $100, а для программы на Java для получения одинакового «фана и экспиреенса» — за $10'000
А назовёте программу на C++, которая имеет одинаковый фан и экспириеенс, сравнимый с IDE от JetBrains? И чтобы при этом она работала на таком ноуте (2GiB RAM, Atom).
Я вот не знаю такой. Может быть, когда она появится, на таком ноуте она тоже будет тормозить… В любом случае, сравнить Idea пока не с чем.
В общем, пока что тормозит только Idea на откровенно слабой для неё системе, и Vuse, а больше названий я не увидел. Но 2 программы это далеко не всё что есть в мире java.
Ну вот, наконец-то назвали вторую тормозящую программу.Как вы думаете — почему мне так сложно это сделать? Потому что я не люблю Java? Нет — потому что я не люблю тормоза. И в результате программ на Java у меня не мало, а очень мало. И они все — начиная от IDE и кончая нашими внутренними системами сборки — страшные монстры жрущие ресурсы «как не в себя».
Тут вас просили: приведите лучше примеры реально программы на Java, которая «летает» — а мы сравним её с аналогом на C++. Только не бенчмарк, а реальную программу, пожалуйста.
Тут вас просили: приведите лучше примеры реально программы на Java, которая «летает» — а мы сравним её с аналогом на C++.
https://habrahabr.ru/post/305894/#comment_9709242
Вот только сравнивать-то особо не с чем. IDE от JetBrains по фичам далеко впереди студии, а уж других ИДЕ и подавно. Профайлеры jvm написанные C++ вряд ли есть.
флеш плеер у вас тормозит? Насколько знаю, он активно использует жава код, просто неявно. На самом деле, жаву использует много прог, но вы про это просто не догадываетесь. Они статически прилинковали libjvm — и юзают ее. Они не тормозят — и поэтому вы думаете что это не java.
Пример из жизни — json_spirit ел 80% проца, qt json парсер — ест около 15 (и при этом он архитектурно убог, что такое container factory — авторы еще лет 10 знать не будут). java-парсер ест 1...5% (что в пределах погрешности). Правда, пришлось написать свой парсер, с плюшками. Стандартные убоги, с неправильно расставлеными try-catch и неверной архитектурой. Стандартные тоже наверное подтормаживали бы.
Так что, на плюсах тоже дохрена тормозящих приложений. Просто считается, что если тормозят плюсы — это хреново написаное, а если тормозит на java — это «тормозит java».
Про Vuze — на практике знаю, что были нормальные сборки, были тормозные. Это не от языка зависит. Помнится натыкался на пару клиентов вполне себе плюсовых, которые тормозили не слабее.
А теперь проведём мысленный эксперимент: поставим на этот ваш «печатную машинку сестры» MS Visual Studio — ну как, не тормозит?Visual Studio 6? Нет — не томозит. .NET был частично переписан на CLR для получения «фана и экспириенса» с покупкой нового железа, увы.
Разработка ПО изначально не приспособлена эффективно работать на дохлых машинах.Нет — это совренные IDE не рассчитаны на это. Только не надо про reflection и прочее. Visual Basic или старые версии Delphi без CLR точно также позволяли и формочки таскать и свойста типов смотреть и многое другое. Потребляя в разы меньше ресурсов.
Давайте прикинем по требованиям: если я правильно помню 200 метров оперативки ей хватало за глаза. Современная IDE от JetBrains в полном фарше на среднем проекте съедает гиг. При том, что у вас всего 2 гига на одноядерном атоме, полюбому, в винде…
В общем у меня на такой конфигурации тормозит _всё_ ПО… Java, браузеры, системные утилиты, да даже сама ОС.
Современные IDE не рассчитаны на использование питекантропами, например, и что? Они дают функционал. Много функционала. Функционала который ускоряет кодирование, функционала, который помогает бороться с ошибками. За всё нужно платить. Ну а если вам достаточно этих динозавров, так почему бы сразу на vim не уйти?
Так что предоставляя НА ПОРЯДКИ худший функционал они потребляют В РАЗЫ меньше ресурсов. ИМХО невыгодный обмен.
А вы более древнюю VS могли назвать?Мог бы. Они тоже не тормозят :-)
Давайте прикинем по требованиям: если я правильно помню 200 метров оперативки ей хватало за глаза.200 метров? Вы, я извиняюсь, ох$нели? 20-30MiB. Больше — если операционка требует больше. На своём Pentium MMX с 64MiB памяти я спокойно ей пользовался под Windows 95 OSR2, на машинках с 16MiB — да, были тормоза, скорее всего на 32MiB она бы «слегка подтормаживала при запуске». Если Windows 2000 поставить или XP, то да, потребуется больше — но тут не в Visual Studio дело.
Современная IDE от JetBrains в полном фарше на среднем проекте съедает гиг.Я не знаю что такое «средний проект». Кому и Chromium (на котором Visual Studio, я извиняюсь, «сворачивается в трубочку») — «средний проект». Но на «Hello, world!» уже требуются сотни мегабайт.
Она не тормозит не потому, что вся из себя такая хорошая, а потому, что функционал у неё резко меньший.Не надо про «функционал», пожалуйста. Даже если отключить в Visual Studio .NET или IDEA вообще всё что можно — они тормозят. Менюшки медленно открываются, переключение между закладками тормозит, да даже если просто текст набирать — можно тормоза заметить.
В общем у меня на такой конфигурации тормозит _всё_ ПО… Java, браузеры, системные утилиты, да даже сама ОС.Мне вас жаль. А у моей сестры её любимый MS Office 2000 не тормозит. И Chrome — тоже. И даже MPC не лагает, представьте себе!
Современные IDE не рассчитаны на использование питекантропами, например, и что? Они дают функционал. Много функционала.Давайте не переводить стрелки, а?
Исходный тезис был прост: Java == неумеренное потребление ресурсов — в первую очередь памяти, но и CPU тоже.
Этот тезис вашими рассказами про «много функционала» ничуть не опровергается. Скорее наоборот.
Ну а если вам достаточно этих динозавров, так почему бы сразу на vim не уйти?Кто вам сказал, что я не использую Vim?
Так что предоставляя НА ПОРЯДКИ худший функционал они потребляют В РАЗЫ меньше ресурсов. ИМХО невыгодный обмен.Когда как. IDEA я тоже иногда использую (правда реже, чем тот же Vim).
Но правда заключается в том, что в теории возможны четыре варианта:
1. Программы, которые требуют чудовищное количество ресурсов и мало чего умеют.
2. Программы, которые требуют чудовищное количество ресурсов и обладают развитым функционалом.
3. Программы, которые не требуют особо много ресурсов и мало чего умеют.
4. Программы, которые не требуют особо много ресурсов и обладают развитым функционалом.
Вы утверждаете, что программы из квадранта 4 были вытеснены программами из квадранта 2 — что правда. Программ из квадратна 4 мало и со временем они, обычно, отстают от программ из квадранта 2 (к возможностям Оберон-системы IDEA шла годы, хотя сейчас, конечно, она получила много новых фич), но проблема в том, что Java напрочь исключает квадранты 3 и 4.
И никакие рассказы про «много функционала» этого не изменят. Да и вообще, мы статья обсуждаем про что? Про то, что «JIT-компилятор оптимизирует не круто, а очень круто»! Ну и хде? Хде эта оптимизация? Почему нам опять поют песни про функционал, а не про то, что это позволяет встроить Java в систему управления холодильников за три с половиной цента?
Почему нам опять поют песни про функционал, а не про то, что это позволяет встроить Java в систему управления холодильников за три с половиной цента?
Эта часть шкалы тоже представлена в J2ME, JavaCard и всяких минималистичных OSGi-профилях. Только функциональность там урезанная, естественно.
J2ME — почил в бозе, слава богу. О покойниках либо хорошо, либо ничего.
А где применяются «минималистичные OSGi-профили»? Нет, мне правда интересно. Неужели какое-то из обещаний, которые помогли «продать» Java (напомню что изначально вся петрушка затевалась ради IoT (тогда, правда, это направление проходило под кодовым названием «Smart Appliances»), но, традиционно для Java, из этого ничего не вышло. Неужели кто-то ещё «не наелся»?
Часть OSGi профилей можно отнести к эпохе J2ME (всякие CDC environment). Из более тяжелых вещей — Eclipse Kura, например. Оно живёт и развивается, но я не знаю, кто использует в боевом режиме.
Другой пример — microej, список клиентов вполне неплох. Ещё на ум приходит Excelsior JET Embedded с их AOT-компилятором.
У меня тоже сложилось впечатление, что в основном использование java в embedded — это hype (как и прошлый заход с jazelle), но то что ощутимое число фирм её пилят намекает, что покупатели есть. Всякие entertaiment-системы, HMI и т. п., где очень хочется взять толпу индусов и быстро выкинуть продукт на рынок.
При использовании ARM9/ARM11/Cortex-A с разумным количеством памяти использование java выглядит вполне реалистично.
У меня тоже сложилось впечатление, что в основном использование java в embedded — это hype (как и прошлый заход с jazelle), но то что ощутимое число фирм её пилят намекает, что покупатели есть.А я вот в этом — совсем не уверен. Java — это такой мыльный пузырь, вокруг которого — куча шума и очень мало сути.
Jazelle — это такая себе типичная Java-история: мы сделаем технологию, которая будет ускорять Java и внедрим её во все наши процессоры, вау! Звучит круто, заманчиво. Но когда начинаешь разбираться, то выясняется, что в результате — вышел пшик: Jazelle призвана исполнять определённый процент операций «в железе» и при этом она реализована во всех, без какого-либо исключения процессорах после ARM7EJ. Круто, да? Но есть одна маленькая беда: процент ускоренных операций может быть нулевым, а начиная с ARMv8 он обязан быть нулевым!
И вот так — веде и всюду. Сплошной Изумрудный город. Когда нет возможности сделать всё вокруг из настоящего изумруда — мы раздаём всем жителям и посетителям очки с зелёными стёклами.
Как вы думаете — почему я так резко отрицательно отношусь к Java и достаточно спокойно — скажем к C#? С чисто технической точки зрения — это почти одно и то же, но разработчики C# — не лицемерят. Они не пытаются выдать нечто без колёс и мотора за «удешевлённое авто» и нечто без крыльев и не летающее — за самолёт.
Если им не удаётся сделать так, чтобы приложение на управляемом коде работало так же быстро, как нативное — они об этом честно говорят, делают возможность вызывать нативный код из CLR и на этом успокаиваются.
Подход же Java — это продолжать заявлять «что скорость работы Java-приложения мало отличается от скорости работы приложения на C++» (притом что увидеть ложность этого высказывания, в общем, не составляет труда), говорить о том, что нечто без байткода и управления памятью — это по прежнему Java (но только когда это делает Sun/Oracle, конечно — когда то же самое делает Google, то это, разумеется, страшный грех и нужно за это отсудить 100500 миллиардов), называть чёрное белым и вообще делать вид, что небо у нас — зелёное (если так партия сказала). Но признать свою ошибку и назвать белое белым, а чёрное чёрным? Нет, этого сделать никак нельзя!
Можете не извиняться, вам это не подходит. Ну а конкретную размерность я уже не помню. По Win95 — извините, но она сама жрёт минимум те самые 16 мегабайт — без свапа вы на 32х метрах очень мало что запустите… и покрашитесь с невозможность аллоцировать память. Скорость дисков того времени вам напомнить? Оно не смогло бы не тормозить. Ну а по накладным расходам — спасибо, что сами о них написали. Не придётся тыкать носом. На той вашей сестринской «печатной машинке» какая ОС? Сколько она оперативки выжирает? Ну а в отличие от производительности — с памятью вопросов нет, Java действительно её любит. Тому же Idea очень хочется скушать около гига. И начинается та же свистопляска со свапом… И это, по вашему, java виновата?
>Я не знаю что такое «средний проект». Кому и Chromium (на котором Visual Studio, я извиняюсь, «сворачивается в трубочку») — «средний проект». Но на «Hello, world!» уже требуются сотни мегабайт.
Средний проект — порядка 100 тысяч строк кода (включая аннотации и всяческие xml типа спрингового контекста). Не на «hw» требуются сотни мегабайт а на функциональность, которая позволяет эффективно работать с крупными проектами (включая кеши различных уровней, например AST, синтаксический анализатор и прочие плюшки).
> Не надо про «функционал», пожалуйста. Даже если отключить в Visual Studio .NET или IDEA вообще всё что можно — они тормозят. Менюшки медленно открываются, переключение между закладками тормозит, да даже если просто текст набирать — можно тормоза заметить.
Т.е. механизмы (архитектуру) подключения этого функционала вы игнорируете? Кастомизируемость UI тоже побоку? Вы физически не можете отключить все плюшки современных IDE. Только снизить их количество. Ну и на Intel Atom c 2мя гигами оперативы… у меня вот в такой конфигурации браузеры тоже только в путь тормозят… Они, видимо, тоже на managed языках написаны, да?
> Мне вас жаль. А у моей сестры её любимый MS Office 2000 не тормозит. И Chrome — тоже. И даже MPC не лагает, представьте себе!
А мне жаль вашу сестру. Пользоваться морально устаревшим софтом и хромом в одну-две вкладочки — тот ещё экспериенс… И да, про MPC не надо мне рассказывать. На Athlon XP 2100+ он тормозил на XP-шке при толстых видяхах, с чего он на более слабом Atom'е-то будет летать? Или вы только хардварно-декодируемое видео смотрите?
> Давайте не переводить стрелки, а?
Исходный тезис был прост: Java == неумеренное потребление ресурсов — в первую очередь памяти, но и CPU тоже.
Этот тезис вашими рассказами про «много функционала» ничуть не опровергается. Скорее наоборот.
Ути-пути. Вы на всех наезжаете, а на вас даже не дыши? Впрочем, если вы приняли питекантропов на свой счёт — поздравляю, вы лузер. Потому что я специально переписал первый вариант, в котором хотел пройтись по вам, на нейтральный, в котором я поминаю сильно «устаревших» (они бы хоть кнпоку смогли нажать?) персонажей. И да, исходный тезис «Java тормозит». Про память там ни слова. И с памятью, согласен, Java в 1.5-3 раза более прожорливая, чем C. Но если дефицит памяти специально не создавать (повышая объём съедаемого GC времени работы) — java имеют сравнимую с c++ производительность на многих классах задач.
> Кто вам сказал, что я не использую Vim?
> Когда как. IDEA я тоже иногда использую (правда реже, чем тот же Vim).
Кхм… так и напрашиваются слова про диагноз… Хотя тут я скорее всего не прав — вы же не на managed языках пишете? На каком-нибудь с++?
> И никакие рассказы про «много функционала» этого не изменят. Да и вообще, мы статья обсуждаем про что? Про то, что «JIT-компилятор оптимизирует не круто, а очень круто»! Ну и хде? Хде эта оптимизация? Почему нам опять поют песни про функционал, а не про то, что это позволяет встроить Java в систему управления холодильников за три с половиной цента?
Где? Ну вот возьмите свою банковскую карту — не исключено, что она используется https://ru.wikipedia.org/wiki/Java_Card. Это если говорить про оптимизацию по памяти, о которой вы вдруг посреди спора вспомнили. Стандартная версия Java плохо подходит для embedded устройств. Да и потребности в этом мало. Впрочем бывают исключения из данной ситуации — https://en.wikipedia.org/wiki/Blu-ray#Java_software_interface
Если же говорить о производительности (с чего и начался весь срач «Java тормозит») — то современная Java при достаточных ресурсах по памяти, ещё раз повторюсь, мало отличается по производительности от c++.
А про функционал вспомнили, когда вы начали припоминать динозавров, утверждая, что они не тормозят.
И вы свои квадранты забыли разбить по третьему вектору — требованиям к производительности железа. Это не ресурсы (память).
Ну а конкретную размерность я уже не помню.Если не помните — то зачем выступаете?
По Win95 — извините, но она сама жрёт минимум те самые 16 мегабайт — без свапа вы на 32х метрах очень мало что запустите… и покрашитесь с невозможность аллоцировать память.Вот только не надо грязи. Windows нормально работает в 16MiB. Вот на машинках с 8MiB, которые нам как-то поставили — да, туго было, там только Windows 3.x нормально ходила. А на 32MiB уже можно и Windows98 поставить (да-да, с позиций современного дня у них «почти одинаковые требования… то есть очень мало» — а на практике Windows98 сжирала, за счёт интеграции Active Desktopа почти вдвое больше памяти).
Оно не смогло бы не тормозить.Вот прямо даже так? А вам напомнить что Visual Studio 6 — это 1998й год? Год, когда Pentium MMX — это была норма (Pentium II только-только появился и мало у кого был), а 64MiB памяти — максимум, который поддерживал славный 430TX? Или вы хотите сказать, что тогда прям у всех разработчиков стояла самая топовая конфигурация, какая тогда была возможна?
На той вашей сестринской «печатной машинке» какая ОС?Windows XP, однако. Зачем там больше?
Тому же Idea очень хочется скушать около гига. И начинается та же свистопляска со свапом… И это, по вашему, java виновата?Вы же сами вроде ответили:
Ну а в отличие от производительности — с памятью вопросов нет, Java действительно её любит.Да, конечно Java виновата — тут даже вопросов нет. Заметьте, что «скушать около гига» — это изрядная нагрузка и на процессор, не только на память, байтики не сами прыгают…
Ну и на Intel Atom c 2мя гигами оперативы… у меня вот в такой конфигурации браузеры тоже только в путь тормозят…С выключенным JavaScript'ом и вырезанным CSS? Позвольте мне не поверить…
Они, видимо, тоже на managed языках написаны, да?Увы. В современных браузерах изрядная часть функционала написана на языке который, похоже, существует для того, чтобы в ответ на «но хуже Java быть уже ничего не может, ведь так» «оптимистично» ответить «нет — может, ещё как может».
На Athlon XP 2100+ он тормозил на XP-шке при толстых видяхах, с чего он на более слабом Atom'е-то будет летать? Или вы только хардварно-декодируемое видео смотрите?Вот давайте не путать божий дар с яичницей. Понятно, что если вы в видеопроигрыватель засунете 4K видео, которые процессор физически не может переварить — то тут уже ничего не сделать. Я про интерфейс. Когда я смотрю видео на этой самой «печатной машинке» — да, оно может дёргаться и замирать. Но перемотка — работает без «залипаний», выход в меню — тоже не тормозит. И окошки нормально таскаются. А вот на телефоне со сравнимой конфигурацией — я наблюдаю именно такой «фан и экспириенс»: постоянные «лаги» и «залипания». Во многом — потому что Java сжирает все ресурсы, а 10x запаса по мощности, чтобы это скомпенсировать у телефона нет.
Ненешние флагманы, впрочем, наконец-то решили эту проблему — грубой силой: четырёх-восьмиядерные процессоры и гигабайты памяти.
Ну вот возьмите свою банковскую карту — не исключено, что она используется https://ru.wikipedia.org/wiki/Java_CardКак же вы любите «лезть в бутылку».
Вы по своей ссылке-то ходили нет? Цитирую: многие возможности языка Java не поддерживаются в Java Card, например, типы char, double, float и long, ключевое слово transient, перечислимые типы (enum), многомерные массивы, финализаторы, клонирование объектов, потоки.
На практике — всё ещё хуже, Wikipedia недоговаривает. Я-то с этой платформой работал, а вы — сюдя по тому, что на это позорище ссылаетесь — нет. Финалайзеров там нет потому что работы с динамической памятью там нет в принципе. В резльтате получаем чудо-юдо, где все массивы и объекты — глобальные (удалять их нельзя никак, а время жизнь кардлета начинается не тогда, когда вы карточку в банкомат засовываете, а когда вы оный кардлет прошиваете — кончается, соответственно, когда его удаляют), никакие Java-библиотеки использовать нельзя (много вы знаете библиотек, не создающих никаких объектов за всё время своей жизни?).
Какое отношением это поделие вообще отшение имеет к Java? Если смотреть на него с инженерной, а не маркетинговой, точки зрения?
Если же говорить о производительности (с чего и начался весь срач «Java тормозит») — то современная Java при достаточных ресурсах по памяти, ещё раз повторюсь, мало отличается по производительности от c++.Мало отличается — это, по вашему, во сколько раз медленнее? В два раза? В десять? Ну если подобное отличие для вас ерунда — то да, наверное. А я таки руководствуюсь мнением Кнута (да-да, того самого, который изрёк знаменитое изречение, которое очень любят цитировать любители Java, про «преждемвременную оптимизацию»): «В устроявшихся инжинерных дисциплинах улучшение на 12%, достижимое без черезмерных затрат, никогда не считается несущественным и я верю что такая же точка зрения должна быть применена в программировании» (Knuth, Donald (December 1974). «Structured Programming with go to Statements». ACM Computing Surveys 6 (4): 268.)
И, как я уже сказал, я пока не видел ничего, написанного на Java, что укладывалось бы в эти 12%.
На моей практике на 8Мб W95 вообще не завелась. На 12ти — да. Кстати устанавливалась 6 часов… Intel80386DX + сопр. Можно я буду его тормозом называть за это? Нет? А почему? Вы же Java называете тормозом, не давая ей достаточно ресурсов.
> Вот прямо даже так? А вам напомнить что Visual Studio 6 — это 1998й год? Год, когда Pentium MMX — это была норма (Pentium II только-только появился и мало у кого был), а 64MiB памяти — максимум, который поддерживал славный 430TX? Или вы хотите сказать, что тогда прям у всех разработчиков стояла самая топовая конфигурация, какая тогда была возможна?
И вы прям помните, как на 32ти метрах оно летало? И вот ну совсем не тормозило? Извините, но у меня страшное подозрение, что вы лукавите. Впрочем, если это было единственное приложение и достаточно мелкий проект — возможно так и было.
> Windows XP, однако. Зачем там больше?
Ради обновлений безопасности? Ради совместимости с современным железом (внешние устройства)? Ради совместимости с современным ПО? (Хотя с такой конфигурацией последний вопрос не самый актуальный… это действительно печатная машинка, незачем туда ПО ставить).
> Да, конечно Java виновата — тут даже вопросов нет. Заметьте, что «скушать около гига» — это изрядная нагрузка и на процессор, не только на память, байтики не сами прыгают…
Если память не дико фрагментированная — хрен там, а не изрядная нагрузка на процессор. Java аллоцирует под себя память максимально доступными блоками (т.е. будет доступно подряд гиг и ей он будет нужен — она его целиком и сожрёт). Да и это накладные расходы запуска приложения, а не его работы.
И заметьте, если вы не соблюдаете блок «системные требования», то виновато не ПО, которое тормозит/падает, а вы. Надо это чётко понимать.
> С выключенным JavaScript'ом и вырезанным CSS? Позвольте мне не поверить…
Позвольте мне спросить — зачем вам браузер?
> Увы. В современных браузерах изрядная часть функционала написана на языке который, похоже, существует для того, чтобы в ответ на «но хуже Java быть уже ничего не может, ведь так» «оптимистично» ответить «нет — может, ещё как может».
Позвольте мне не согласиться. JS хоть и имеет множество косяков — остаётся вполне вменяемым языком, на котором можно сделать любой web-UI. Заметьте, всё более «эффективное» почему-то мрёт в вебе. Поэтому называть его плохим языком — я бы не спешил.
> Как же вы любите «лезть в бутылку».
Не больше, чем вы.
> Какое отношением это поделие вообще отшение имеет к Java? Если смотреть на него с инженерной, а не маркетинговой, точки зрения?
Не поверите — вы мне не сообщили ровным счётом ничего нового. А поделие это — подмножество языка, эффективно работающее с памятью. Как вы и хотели.
> Мало отличается — это, по вашему, во сколько раз медленнее? В два раза? В десять? Ну если подобное отличие для вас ерунда — то да, наверное. А я таки руководствуюсь мнением Кнута (да-да, того самого, который изрёк знаменитое изречение, которое очень любят цитировать любители Java, про «преждемвременную оптимизацию»): «В устроявшихся инжинерных дисциплинах улучшение на 12%, достижимое без черезмерных затрат, никогда не считается несущественным и я верю что такая же точка зрения должна быть применена в программировании» (Knuth, Donald (December 1974). «Structured Programming with go to Statements». ACM Computing Surveys 6 (4): 268.)
Мало отличается — это мало отличается. На уровне плюс-минус десять процентов. И я не руководствуюсь ничьим мнением. Но вот согласно мнению вами любимого Кнута — Java использовать стоит. Т.к. улучшение сильно больше 12% — время разработки (по сравнению с c++) сокращается в 2-3 раза. Вы просто вбили себе в голову, что java тормозная… но ведь нет! Она может решать некоторые классы задач на вполне нормальной скорости. Инженерная аналогия — стоит ли строить мост в 4 полосы за n+m денег (стройка + инженерные расчёты) и t времени или лучше построить 2 двухполосных моста за n+m*2/3 денег, каждый из которых можно построить за t/3 времени? По сути в этой аналогии достигается экономия на расчётах (проще и частично перекликаются), экономия на времени (можно одновременно строить) и потенциальная инфраструктурная плюшка — легче развязывать потоки машин + легче обслуживать (в крайнем случае один мост можно временно закрыть).
> И, как я уже сказал, я пока не видел ничего, написанного на Java, что укладывалось бы в эти 12%.
А я видел мало тормозящих Java-программ. И много — не тормозящих. И в большинстве случаев тормоза случались на слабых по объёму памяти машинах.
На моей практике на 8Мб W95 вообще не завелась. На 12ти — да. Кстати устанавливалась 6 часов… Intel80386DX + сопр. Можно я буду его тормозом называть за это?Да, конечно — по сравнению с Windows 3.x это был монстр и тормоз. Но на 8MiB он таки заводился — если у вас этого не получилось то это скорее говорит о кривых руках, чем о тормознутости Windows 95. Официальные требования вообще о 4M говорят. Вы точно уверены, что вас память не подводит и это была Windows 95, не Windows 95 OSR2 (реально требовавшая уже 8MiB) или Windows 98 (которой было нужно ажно 16MiB)?
Нет? А почему?В том-то и дело, что нипочему. Я — человек простой и называю чёрное чёрным, а белое — белым, представьте себе. Windows95 — это очень тяжёлая операционка, если сравнить её, скажем, с Windows 3.x (Windows 3.0 вполне ходила на 1MiB, хотя для Windows 3.1 этого, уже, в общем, стало не хватать — официальные требования не врут) — но вполне себе лёгкая, если сравнивать её с Windows NT (эта вообще каких-то космических ресурсов требовала). Не очень понятно, почему вы считаете, что я буду это отрицать.
В обоих случаях известно за что вы платите: в случае с Windows 95 — за возможность написания 32-битных многопоточных программ (ну и за красивые кнопочки, конечно, но красивые кнопочки и в Windows 3.x можно было нарисовать, в общем-то), в Windows NT — за возможность изолировать программы друг от друга (с некоторыми оговорками, правда, ради скорости и уменьшения потребления ресурсов Windows NT 4.0 сделала большой шаг назад).
Хотите ли вы за эти красивости платить повышенными требования к железу — решать вам, но назвать их «незначительно отличающимися» я не могу: даже требования Windows 95 и Windows 98 прилично отличаются друг от друга (официальные, кстати — тоже), а Windows NT — так вообще тормоз…
То же самое и с Java: да, я знаю, что она позволяет использовать труд условных «неквалифицированных индусов» и тем самым ускорить разработку. Но от этого она не перестаёт быть тормозным, тяжёлым, монстром. Это просто разные вещи, не нужно их в одну кучу валить.
За редакцию не скажу (хотя никаких дополнительных символов после «95» я в названии не видел). Но точно 95. 98ая на 386 как-то не хотела устанавливаться.
> В том-то и дело, что нипочему. Я — человек простой и называю чёрное чёрным, а белое — белым, представьте себе. Windows95 — это очень тяжёлая операционка, если сравнить её, скажем, с Windows 3.x (Windows 3.0 вполне ходила на 1MiB, хотя для Windows 3.1 этого, уже, в общем, стало не хватать — официальные требования не врут) — но вполне себе лёгкая, если сравнивать её с Windows NT (эта вообще каких-то космических ресурсов требовала). Не очень понятно, почему вы считаете, что я буду это отрицать.
Да вы не «простой человек» и не «называете чёрное чёрным». Вы действуете как фанатик. И машину окрашенную с одной стороны чёрным, а с другой — почти белым называете чёрной. И из-за своего отношения (а не реальных проблем языка и платформы) вы упорно не хотите слушать оппонентов, измором пытаетес всех убедить, что «java тормозит», передёргиваете слова (был спор о производительности, вы откуда-то вытащили потребление памяти)… Вот поэтому я и считаю, что вы будете отрицать.
> Хотите ли вы за эти красивости платить повышенными требования к железу — решать вам, но назвать их «незначительно отличающимися» я не могу: даже требования Windows 95 и Windows 98 прилично отличаются друг от друга (официальные, кстати — тоже), а Windows NT — так вообще тормоз…
Заметьте, вы ни разу не сказали «тормоза» по отношению к W95. А ведь там та же ситуация — за большие возможности приходится платить большим потреблением. Только Java при достатке памяти на многих классах (специально для отмечаю — не на всех! НО на многих!) задач имеет производительность сравнимую с c++.
> То же самое и с Java: да, я знаю, что она позволяет использовать труд условных «неквалифицированных индусов» и тем самым ускорить разработку. Но от этого она не перестаёт быть тормозным, тяжёлым, монстром. Это просто разные вещи, не нужно их в одну кучу валить.
Да плевать на индусов. В c++ они тоже работают. И драйверы на C пишут. Причём тут индусы вообще? Речь именно об ускорении разработки при получении сравнимой производительности… платить приходится объёмами памяти — да. И если вы назовёте её тяжёлым монстром — никто не возмутится. Если вы скажете, что на каких-то классах задач она тормоз — тоже все промолчат. А вот общая классификация как «тормозной тяжёлый монстр» — это извините, наглая ложь. И вы фанатично(!) пытаетесь это сказать (даже не доказать). Кстати, в соседнеё теме про планируемые изменения в c++ вас тоже легко узнавать по горячности и абсолютности утверждений.
Разработчику не жалко потратить десятки а иногда сотни тактов процессора чтобы избежать лишнего доступа в кеши процессора или в оперативку.А давайте не обобщённо «десятки и сотни», а более предметно. Возьмём данные отсюда (они, правда, немного устарели, но порядок величин показывают верно): L1 — 3-4 тактов, L2 — 10-15 тактов, доступ в память — ~200 циклов (на серверных процессорах есть ещё L3 — он где-то посередине).
То есть: память — это сотни тактов, L2-L3 — десятки, L1 — единицы.
А теперь фокус: байткод и интерпретатор зачастую вместе занимают меньше места чем соответствующий ассемблер.Это ни разу не фокус, этим пользовались ещё разработчики Excel'я в далёком 1985м году, чтобы уместить своё творение на минимальное число дискет. Размер — это действительно экономит. А вот получить этого выигрыш в скорости — штука «посильнее „Фауста“ Гете».
Кеш L1 (самый важный) — он маленький. По нынешним меркам — просто крошечный. PowerPC 1991 года — 16K, Pentium MMX 1997 года — 32K, но даже в самом современном Skylake — всего лишь 64K, увы. Вы серьёзно хотите сказать что у вас туда уместится и приложение и JIT и скомпилированный код? Который при этом ещё и будет быстрее того, что породил компилятор C++?
Достигается это тем что JVM байт-код это хорошо упакованные высокоуровневые инструкции, которым могут соответствовать десятки команд ассемблера.Правильно. Но есть одна проблеммка: интерпретировать его долго, мы тут не зря JIT'ы обсуждаем. А вот скомпилированный JIT'ом код — это не только, собственно, вычисления, но ещё и дополнительные проверки и логика на случай «изменения направлений движения» и прочее. И занимает этот код больше, чем то, что породил C++. Ненамного, но больше. А ваш этот суперлаконичный код где-то сидит — это тоже сверх того кода, который нужно, собственно, исполнить.
Вот так и получается что действия, которые выполняются относительно редко (95% всей логики), логично интерпретировать.Потому что скорость работы этого кода ни на что не влияет — да, именно так. Это и в программах на C++ так и в Java и где угодно. Но это не очень важно — важна скорость работы «горячего» кода.
Готов поспорить что если гипотетически скомпилировать ее в машинные команды (реально не получится ибо рефлекшн), то эти 5-20 минут разогрева потратятся просто на загрузку разбухшего кода в память и прогрев кешей.А это — уже от архитектуры приложений зависит. Chrome имеет сравнимое количество кода — но «прогреваться» после запуска ему не нужно.
Да и вообще — вы просто посчитайте. Даже очень плохонький винчестер даёт скорость загрузки порядка 5-10MiB в секунду при дикой фрагментации диска. Вы всерьёз хотите сказать, что у вас Idea загружает в себя несколько гигабайт кода?
В общем JIT и Java — это такой «путь китайского комсомола»: сначала насоздаём себе трудностей, а потом будем героически их преодолевать.
Достижения JIT'остроителей впечатляют, да, но не следует забывать что все усилия их разработчиков привели лишь к тому, что мы получили скорость «почти такую же как при использовании технологий 30-летней давности».
Такой себе Space Shuttle: то, что летает — это чудо, это реально офигительный подвиг, разработчики сотворили почти немыслимое. А вот то, что это чудо вообще кто-то задумал, не то, что реализовал — это ошибка. Большая ошибка.
Посмотрел я мандельброт. Ну что сказать, автор некорректно написал java-код — и поэтому, предположительно, поймал на нем эффект частой миграции данных между кэшами (в данном случае — это true sharing). Конкретно проблемы с этой строчкой: while((y=yCt.getAndIncrement())<out.length) Вы представьте: каждое getAndIncrement() должно подтянуть кэшлайн с новым значением себе. Ясное дело — это около out.length кэш-промахов. Причем, там тяжелый случай кэш-промаха, предположительно. В отличии от OMP, которое разделило диапазоны до старта цикла.
Ну и плюс, запущено без прогрева. Никто не обещал, что до прогрева оно будет летать.
Ну и плюс автор вывод c++ направил в файл (по крайней мере, возможность предусмотрел — третьим параметром идет имя файла), а вывод java направил в консоль. Консоль — штука не очень быстрая и непредсказуемо-тормозная, так что он померял в итоге непонятно что. Естественно, я его тест переписал, направив и java тоже в файл. по-сути, заенил одну строчку на: OutputStream stream = new java.io.FileOutputStream(«xyz»);
Результаты:
# time java -server -XX:+TieredCompilation -XX:+AggressiveOpts Mandelbrot 16000 xyz
real 0m6.211s
user 0m22.394s
sys 0m0.117s
(^^^^это i586 версия)
# time /usr/local/jdk1.8.0_91/bin/java -server -XX:+TieredCompilation -XX:+AggressiveOpts Mandelbrot 16000 xyz
real 0m5.774s
user 0m20.944s
sys 0m0.151s
(^^^^ это x64)
# time ./mandelbrot.gpp-9.gpp_run 16000 xyz
real 0m7.330s
user 0m27.380s
sys 0m0.039s
и это результат когда java с атомиками работает. Если переписать без них — можно добиться еще большего. Это на amd, кстати.
На компе стоит i586 операционка, поэтому OMP версию пришлось перекомпилить с ключиком -m32. Так же, java там 1.8.0_51 (тоже i586, ясное дело), обновляться до 1.8.0_92 было влом.
Результаты:
# /tmp/3$ time ./mandelbrot.gpp-9.gpp_run 16000 xyz
real 0m31.277s
user 1m1.756s
sys 0m0.132s
# time java -server -XX:+TieredCompilation -XX:+AggressiveOpts Mandelbrot 16000 xyz
real 0m27.763s
user 0m54.036s
sys 0m0.300s
Интересно, зачем вы с -XX:+AggressiveOpts
запускаете? Это сознательный выбор или просто вам кто-то когда-то сказал, что так что-то будет быстрее?
На 64-бит -server
и -XX:+TieredCompilation
работает по дефолту, а -client
вообще игнорируется.
Я — не использую, использовал автор исходников. Там строка запуска (а в случае с++ версии — строка запуска компилятора тоже) под исходником находится. Было 2 ночи, собирался спать, думал по-минимуму — копипастил по-макимуму.
Наверное, если бы результат вышел плохой, это заставило бы задуматься и что-то сделать, но результат оказался хорошим — и я на этом остановился.
В вашем случае -XX:+AggressiveOpts
скорее всего ни на что не влияет. Просто это довольно дурная опция. В разных версиях JVM она может включать разные штуки, которые не всегда нужны (не зря же они выключены по дефолту). Поэтому не стоит пользоваться ей слепо, не зная, что конкретно она включает в вашей JVM и нужно ли это вам.
benchmarksgame.alioth.debian.org/play.html#contribute
> Ну и плюс, запущено без прогрева. Никто не обещал, что до прогрева оно будет летать.
benchmarksgame.alioth.debian.org/sometimes-people-just-make-up-stuff.html#jvm-startup-time
> Консоль — штука не очень быстрая и непредсказуемо-тормозная, так что он померял в итоге непонятно что.
/dev/null
benchmarksgame.alioth.debian.org/how-programs-are-measured.html
в любом случае, у меня результаты получаются не такие, как у него.
Сейчас попробовал его fannkuch-redux (java тоже некорректно написана), запускал раз 10 оба примера. Вердикт — они по времени работают одинаково, 11...12сек, и я бы не сказал, что имеется перевес в чью-то пользу. Наверное, можно было бы усреднить и получить результат, но нет смысла. т.к. все равно в java версии использованы атомики, а плюсовая разделена на независимые треды заранее. т.е. сравнение некорректно.
Не знаю, почему он получил видимую разницу. У него старое железо(«q6600 — проц для широких масс вдвое дешевле» — гугл), а такое железо как раз плохо может работать при конкурентном доступе к данным — то есть как раз с атомиками. Наверное, поэтому. Скорей всего, если написать тесты одинаково, то разница была бы в пределах погрешности.
То есть, несмотря на то, что в теории программы должны быть быстрые, по факту они бывают достаточно быстрыми только в определенных случаях (например, игры обычно неплохо оптимизированы, или тот же Hadoop).
Примерно в середине доклада вроде рассказывает про спекуляции с виртуальными методами тоже (тема статьи)
Читайте и смотрите классику: вот свежий часовой доклад от человека, который задизайнил JIT компилятор хотспота в свое время: https://www.infoq.com/presentations/java-vs-c-performance
Есть сценарии, которых бесконечно много, но можно выделить основные, типа «векторная математика, графика, работа с бд», и так далее.Сценариев, конечно, «бесконечно много», но, в общем, их не так сложно рассклассифицировать.
Начать нужно с конца. Работать всем нашим сценариям предстоит, представьте себе, на CPU. А у CPU есть кеш. 64K, как говорит нам Wikipedia. Который либо поступает в распоряжение программы, либо делится между JIT'ом и программой.
То есть если у нас программа имеет статический профиль (а «суперчудеса» все JIT'ы демонстрируют на статическом профиле), то удел JIT'а — получить результат чуть хуже, чем у приличного статического компилятора. Если же в программе типов много и они меняются часто, то скорость всего хозяйства получается — «ниже плинтуса».
То есть хотя теоретически JIT и может выиграть у компилятора C++, но происходит это примерно так же часто, как солнечные затмения: хорошо если раз за свою жизнь увидите. Можно, конечно, сесть на самолёт и слетать куда-нибудь… тогда чаще. Так часто бенчмарки делают: смотрим на 100500 задач, отбираем парочку где наш JIT особо хорош… вуаля: есть статья. Но если вам нужна не статья в журнал, а программа, то увы: на практике вы этих чудес не увидите.
Тем не менее современные JIT'ы уже дошли, наконец, до состояния, когда вся эта конструкция (убогий, безумно тормозной, байткод — плюс JIT, который призван всё это компенсировать) неплохо работает. При двух непременных условиях, впрочем:
1. Вы должны работать с данными без всякого полиморфизма (иначе JIT не сможет «развернуться»).
2. Вы должны не забывать о том, что если вам нужно загрузить и обработать гигабайт-другой данных, то ваш сервер неплохо бы оснастить несколькими гигабайтами памяти — примерно так втрое больше, чем вам реально нужно. А иначе вам GC всю малину испортит.
2a. Есть, правда, выход: вывести GC «за скобки». Выделить столько массивов простых типов, сколько вам нужно, работать там со смещениями — и вуаля: скорость примерно как у C/C++! Вот только зачем вам при таком подхое Java вообще? Понятно, конечно, что настоящий программист программист может писать фортрановские программы на любом языке… но зачем? Пишите фортрановские программы на фортране — и да пребудет с вами сила!
у CPU есть кеш. 64K, как говорит нам Wikipedia. Который либо поступает в распоряжение программы, либо делится между JIT'ом и программой.
JIT не работает долго на прогретой программе (а джавы сереверные программы работают часто неделями). Реальный профиль работы CPU примерно как на слайде 23 вот этой презентации: http://www.slideshare.net/ZeroTurnaround/vladimir-ivanovjvmjitcompilationoverview-24613146 GC — да — кушает процессор — особенно concurrent, это плата на managed свойства языка, как спору AOT-JIT почти не имеет отношения.
То есть если у нас программа имеет статический профиль (а «суперчудеса» все JIT'ы демонстрируют на статическом профиле)
Ровно наоборот. Как раз статический профиль можно через PGO механизмы подать в gcc/clang и получить идеальный профиль. JIT способен отработать изменения поведения программы и рекомпелироваться. Например, если код, который был прогрет и нормально работал, вдруг начинает бросать exceptions. Кроме того, JVM перемещает скомпелированный код, что позволяет часто взаимодействующему коду находиться вместе, сокращая TLB misses. Наконец, уникальная возможность — можно прицепиться к программе, могда метод с брейкпоинтом уйдет в интерпретатор, после отключения bp обратно рекомпелируется,
1. Вы должны работать с данными без всякого полиморфизма (иначе JIT не сможет «развернуться»).
С умеренным полиморфизмом (а это 2-3 имплементора виртуальной функции) JIT справится, а не хуже AOTа, дальше — беда, как правило — для всех.
ваш сервер неплохо бы оснастить несколькими гигабайтами памяти — примерно так втрое больше, чем вам реально нужно
Это почти справедливо, но это расходы GC, а не JITа. Это другая тема. Я плохо знаком с .NЕT миром, но там есть AOT + GC. Всё тоже самое с точки зрения расхода памяти. И да, не втрое, а примерно +30% для долгоживущих объектов и в 2 раза для «молодого поколения». Это длинная тема.
Есть, правда, выход: вывести GC «за скобки». Выделить столько массивов простых типов, сколько вам нужно, работать там со смещениями — и вуаля: скорость примерно как у C/C++
Это справедливо. Работа со структурами, с массивами структур, с вложенными массивами — самое слабое место Java. Ждём десятку — arrays 2.0, value types и и.п. Но к JIT это не имеет отношения, это слабость языка. JIT в .NET прекрасно работает с массивами структур.
Есть еще одно слабое место именно JIT-a — это автовекторизация. JIT может найти возможность использовать векторные инструкции в простых паттернах, как и GCC/clang, но легко соорудить пример, с которыми ни один компилятор не справится, оптимизация «вручную» победит. AES шифрование например (по этой причине шифрование и хэширование делается интринсиками, а не компилятором).
JIT не работает долго на прогретой программе (а джавы сереверные программы работают часто неделями)
JIT способен отработать изменения поведения программы и рекомпелироваться". Либо первое, либо второе, а одноверменно — примерно как наступление солнечного затемения.
Да, если у вас паттерн использования резко сменился (скажем если к вам вместо обычных запросов вдруг начали посылать один, весьма специфический, в надежде вас за'DDOS'ить), то вы можете что-то отыграть — но как часто это случается?
Это почти справедливо, но это расходы GC, а не JITа. Это другая тема.Это та же тема: «великораспильные языки» против «старой школы».
Объясняю свою позицию: когда-то давно, много лет назад, когда IBM PC 4.77MHz уже немного устаревала, но для школы годилась я столкнулся с «типа крутым редактором» (интересно — как он назывался? сейчас уже не вспомнить, но помню что там были разные фишки типа спеллчекера). И была у него одна проблема: на большинстве машин в классе со 256KiB он не работал, требовал «полных» 640KiB. А ещё он осталавливался на полсекунды каждые примерно секунд пять. На вопрос в духе «а почему собственно» поступил ответ в духе «ту эта, у нас тут немного больше памяти требуется, а ещё задержки от сборщика мусора и байткода — но вы не волнуйтесь, скоро мы всё починим». С тех пор идут годы — и заклинание «вы не волнуйтесь, скоро мы всё починим» в отношении managed языков не меняется. Почему я всю эту конструкцию считаю шарлатанством и выкидыванием денег не ветер.
P.S. Есть ещё второй подобный пример, кстати. Когда C++ (и STL) только появились, то многие высказывали недовольство тем, как там сделано метапрограммирование: вместо того, чтобы дать возможность программисту точно описать — чего он, собственно, хочет в C++ принято порождать программы, которые, если компилировать их без оптимизации, «в лоб», будут порождать терабайты кода — в надежде на то, что компилятор всё «подчистит». И там, тоже, до сих пор это аукается. Я принимаю и Java и C++ (свои задачи они, в общем, решают — хоть и с оговорками), хотя меня до сих пор терзает вопрос: а если бы все миллиарды, которые мы вбухали в попытку (частично успешную) обойти проблемы, которые мы же сами себе и создали — как бы изменится мир? Теперь уже не узнать…
AES шифрование например (по этой причине шифрование и хэширование делается интринсиками, а не компилятором).Там слишком сложный паттерн, чтобы его мог хоть один компилятор в мире распознать и в AES-NI завернуть. Автовекторизация в JIT'ах пока слабее, чем clang'е или gcc — но это, я думаю, временно. Ничего смертельно сложного там нет.
Работа со структурами, с массивами структур, с вложенными массивами — самое слабое место Java. Ждём десятку — arrays 2.0, value types и и.п. Но к JIT это не имеет отношения, это слабость языка.А я, в общем, и обсуждаю в основном язык.
JIT, это знаменитое:
Один пришивает карман, один — проймочку, я лично пришиваю пуговицы. К пуговицам претензии есть?Так вот у меня претенции не к пуговицам, а к тому, что путём увеличения их размера и количества пытаются сделать носибельным фасон костюма, который, по хорошему, вообще не должен был бы использоваться!
Ещё раз прочитайте что вы написали
JIT не работает долго на прогретой программе (а джавы сереверные программы работают часто неделями)
JIT способен отработать изменения поведения программы и рекомпелироваться"
. Либо первое, либо второе, а одноверменно — примерно как наступление солнечного затемения.
Да, если у вас паттерн использования резко сменился (скажем если к вам вместо обычных запросов вдруг начали посылать один, весьма специфический, в надежде вас за'DDOS'ить), то вы можете что-то отыграть — но как часто это случается?
Здесь нету противоречия. JIT стартут вместе с JVM, работает в N потоков, пока не закончится очередь CompileQueue и JVM не придет в некое стабильное прогретое состояние. Компиляция одного метода занимает доли секунд, а приложение работают, часто, неделями. Если требуется рекомпиляция, то основной проигрыш от того, что во время рекомпиляции метод интерпретируется, что на порядок медленнее, но собоственно компиляция проходит быстро и безболезненно. Я как раз готовлю доклад про деоптимизации, так вот довольно сложно даже написать такой тест, чтобы проблема была ощутимо заметна.
А я, в общем, и обсуждаю в основном язык.
Мы же обсуждаем статью «JIT-компилятор оптимизирует не круто, а очень круто»? Здесь мог бы быть любой из более чем сотни языков, которые работают на JVM. Мог бы быть даже .NET + CLR — уверен, что JIT в нем работает примерно также, при этом и «убогого байткода» там нет, и других недостатков, вроде отсутствия массивов структур и контроля для лейаутом
— если профиль динамический — он (по факту, хоть и не собирается) будет динамический и на с++ тоже, поэтому глупо ждать какой-то существенной просадки «ниже плинтуса» производительности в java — но при этом считать что с++ будет по прежнему «летать».
— JIT, в отличии от «приличного статического компилятора» может компилить, используя особенности платформы, на которой работает, и за счет этого тоже что-то выигрывать.
— в 90ых было очевидно, кто тормозит. Сейчас jit компилятор хорош. По сути, g++ — это компилятор, jit — это тоже компилятор. Поэтому, сейчас эти расклады ненастолько очевидны. В jit было вкинуто очень много человеко-часов, а g++ — гнутая софтина, в которой некоторое время (4.9.0) вообще жили критичные баги и всем было пофиг. И нет возможности корректно сравнить jit и c++ на реальных проектах. Даже если сделать 1 проект на два раза на разных технологиях — решающую роль может оказать квалификация/специализация/предпочтения программиста. Поэтому, говорить «происходит это примерно так же часто, как солнечные затмения» — необоснованно. Вообще, на сегодня известен факт: в 99% случаев программа тормозит не в том месте, где думает программист.
— в моих тестах выше по каментам подход «смотрим на 100500 задач, отбираем парочку» не использовался. Надо будет по свободе провести тесты с остальными примерами автора.
— полиморфизм будет тормозным и в с++, ведь от поиска по таблице виртуальных функций не уйдешь. Принципы работы ведь одни и те же. Возможно даже плюсы будут медленней, из за множественного наследования. Более того, jit может выбросить поиск, заинлийнить — и стать быстрым. И это происходит довольно часто. Так что тут, наверное, jit.
— насчет вопроса «зачем вам при таком подхое Java вообще?» Очевидно, обработка гигабайт данных — это, в большинстве случаев, не 100% программы, а скорей 1%. java — для оставшихся 99%, которым ненужно так много памяти.
Итог: я думаю, у вас предвзятое отношение к jit, оно у вас сформировалось исторически — потому, что действительно когда-то было оправдано так считать. Но платформа развивается.
Есть еще интересное социальное явление: когда люди повторяя мантру «жава тормозит», пишут некорректный и тормозной код на плюсах. Я такое реально встречал на практике, например был у нас прецедент: json_spirit либа ела 80% проца. Перешли на java (и плюс размер данных увеличился раза в 3) — кушает 1..5%. Qt-шный json-парсер тоже, кстати, много проца ест. Не 80% конечно, но заметно больше. Так что ненадо жить представлениями 90ых. Отрасль развивается.
Есть еще интересное социальное явление: когда люди повторяя мантру «жава тормозит», пишут некорректный и тормозной код на плюсах. Я такое реально встречал на практике, например был у нас прецедент: json_spirit либа ела 80% проца.С этим спорить не буду — на C++ тоже можно «Г» написать.
Отрасль развивается.Если бы. Отрасль ходит по кругу. Или, скорее — движется по спирали идущей вниз. Вы не поверите, но у меня есть дома вот такая машинка. И на ней — есть GUI (совершенно не тормозящий… ещё бы, целых 66Mhz), редакторы, браузер и прочее (браузер, правда, запускается небыстро, спорить не буду). И он никогда не «уходит в себя» на час! А мой X1 Carbon — уходит! Да, я знаю, AGA поддерживает, в типичном случае, 640x480x256 цветов, а мой X1 — 2560x1440x16777216. Разница в потребной памяти — 48 раз. Но, казалось бы, современные технологии должны компенсировать? Фиг вам. Вот в этом-то и беда. Не туда мы куда-то идём…
Ох, опять… Вы на этих машинах одни и те же приложения запускаете? Скорее всего нет. По возможностям старые программы могут посоперничать с современными? Сомневаюсь.
Как-то глупо было бы, если железо развивалось, а софт не использовал это железо на максимум.
По возможностям старые программы могут посоперничать с современными?В том-то и дело, что могут! По бздынь-бдыщ-какие-изящные-пимпочки — не могут, а именно по возможностям — могут легко. Какой-нибудь MultiEdit по своим возможностям не сильно отстаёт от славного SlickEdit'а — хотя да, он далеко не так красив, но, чёрт побери, он работал в 640KiB! На 4.77Mhz!
Да, существуют программы, которые имеют то, чего принципиально было нельзя сделать на компьютерах 20-летней давности (хотя это ещё поискать нужно: та же Amiga телестудмиями использовалась вплоть до появления TVHD), но подавляющее большинство — требуют ресурсов на порядки (то есть не в 10 раз, а скорее в 100) больше, чем им реально нужно.
Я понимаю почему так выгодно делать с точки зрения зарабатывания денег — но только после этого не надо рассказывать после этого как у нас всё эффективно и хорошо.
Как-то глупо было бы, если железо развивалось, а софт не использовал это железо на максимум.Ещё глупее — делать вид, что все эти JIT-ухищрения приведут хоть к какому-то выхлопу, который увидит пользователь. Нет, они просто позволят разработчикам ввести ещё парочку уровней индирекции, которые сожрут весь выигрыш…
а именно по возможностям — могут легко
Емакс вон тоже может и на старых тачках запускаться. Однако, голый емакс мало кого устраивает, а вот дополнения уже нагружают систему. Я сомневаюсь, что MultiEdit потянет на 640KiB и 4.77Mhz все возможности, которые я использую в своём редакторе.
Ещё глупее — делать вид, что все эти JIT-ухищрения приведут хоть к какому-то выхлопу, который увидит пользователь.
Ну если писать код плохо, то никакие оптимизации не спасут. И уж тем более, не стоит надеяться на JIT.
А пример, который в статье, вполне может встретиться в реальной программе. И автор показал, как он может быть ускорен самой java. А ваши доводы пока что не подтверждены никакими реальными примерами.
Так что лучше я буду выглядеть глупо и верить, что JIT ускорит мой код. Тем более, что я сам видел это неоднократно.
«морду» я и на zx-spectrum кое-как умудрялся делать — и в 48кб помещалось. Естественно, там никто даже не задумывался о том, чтобы работать с таким кол-вом данных, как это есть сейчас. И всякие эти разговоры, что раз в 4к-демо могли впихнуть столько — то у нас вот тут много занимает, они не учитывают, что в 4k-демо подгоняется ТЗ под программу, а в реальной жизни приходится делать наоборот.
Ладно, это нас на философию потянуло. Я лишь говорил о том, что jvm из 90ых — это не jvm-2016. Туда вкинуто много труда, вылизано очень много всего. По сути, даже в 90ых сравнивали технологию, которой всего пару лет, с гораздо более старым и сформировавшимся gcc.
Естественно, там никто даже не задумывался о том, чтобы работать с таким кол-вом данных, как это есть сейчас.Работали с теми данными, которые были тогда. Я лично редактировал файлы в ~300KiB на кружке по программированию на MSX-2 славным редактором mim. Недавно попробовал открыть лог аналогичного размера каким-то редактором под Android — он умер… вернее его система убила.
Мощности современного телефона и MSX-2 сами сравните или вам данные из Wikipedia подтянуть?
Впрочем посмотрим на ваш пример:
— что за телефон (объём и параметры оперативной памяти, объём съедаемый ОС, разрешение экрана)?
— что за приложение?
Ну а в целом ответ-то на него такой: вы знаете на MSX-2 тоже можно было наговнокодить. Это было чуть-чуть сложнее из-за того, что уровней абстракций в коде было меньше и кода было меньше (из-за значительно меньшего функционала).
А простенькое приложение FBReader грузит двухмегабайтный fb2 файл из zip-архива. Спокойно и без проблем.
public int getMyInt(){}
Вы уверены, что не пытаетесь «писать на Фортране» лишь потому, что так привыкли делать, а вовсе не потому, что это действительно «нужно»?
> Круто, конечно, но, может быть, проще было язык поприличнее сделать изначально?
Это всего лишь эмоции, а не аргумент.
Руководствоваться эмоциями при выборе инструмента — не лучшая идея.
При возврате переменной костылем в виде массива из одного элемента нет ни циклов, ни итераторов для уничтожения JITом.
Сделано нормально именно сейчас. У языка Java есть очень крутое свойство: локальную переменную метода может изменить только непосредственно сам этот метод и никто другой. Это существенно упрощает жизнь и спасает от кучи багов, особенно при многопоточном программировании. Не говоря уже о том, как помогает оптимизировать код JIT-компилятору и работать статическим анализаторам. Вы хотите передачу по ссылке? А если вызываемый метод запустит новый тред и обновит переменную уже в нём? Вызвав метод и передав туда локальную переменную, вы не будете знать, когда она изменится. Вся надёжность накроется медным тазом.
Иногда если что-то не сделано, это гораздо лучше, чем если что-то сделано. Тут выбор сознательный и очень хороший. Лучше, когда язык умеет меньше, но ты точно знаешь, что происходит.
Хороший вопрос. В реальном приложении этот метод полностью заинлайнится в точку вызова, причём в разные точки по-разному. Там, где singletonList, он свернётся в чтение поля. Там, где другой тип, будет более сложный код. В один пост подробный анализ этой ситуации уже не лез :-)
logger.log("message {0}", oneArg);
где logger.log принимает на вход строку и массив объектов.
// Проверка на safe-point. С её помощь JVM может забрать контроль у скомпилированного кода, например, для сборки мусора.
test %eax,-0x27b759f(%rip)
не понимаю, как тест позволяет забрать контроль
не понимаю, как тест позволяет забрать контроль
Этот адрес находится на read-protected странице. Происходит прерывание, обработчик которого и взведет java треды на сейфпоинт. Это такой быстрый if. То есть быстрый он тогда, когда идти на safepoint не надо, а если надо — то там и так будет пауза, потомы накладные расходы, связанный с отработкой прерывания минимальны.
Продолжает, конечно. Что с ней сделается-то? А что происходит с компьютером, если программа падает с сегфолтом? Продолжает ведь работать. С точки зрения процесса нет особой разницы, обработчик прерывания в коде операционной системы или в коде текущего приложения (виртуальной машины).
Как продолжить программу дальше? Разрешить рид перед завершением? А как тогда потом поймать другие?
Когда снова надо будет запарковать потоки — снова сменить разрешение на страницу памяти.
И это не обязательно stop the world. Так реализуют, хоть и не в openjdk, механизм per thread safepoint, когда надо гарантировать, что каждый thread зайдет в сервисную рутину, но после того может продолжить работу, не дожидаясь остальных.
И, кстати, даже это оптимизируется в рантайме, например: считается, что NPE — редкое событие. Так что разименование нулевого указателя обрабатывается через сигнал. Но если у вас в методе часто падают NPE, то компилятор перекомпилирует этот метод с явными проверками.
1. Почему в из Hotspot до сих пор не выкинули вообще интерпретатор? Почему Google в V8 сделала это, а Oracle — нет?
2. Какая производительность чистого интерпретатора в Hotspot — кто-нибудь измерял, забавы ради?
3. Почему в явасрачах сразу же не фиксируется базовая установка: Java — для бэкенда, для «серверных» сценариев нагрузки, когда Hotspot выполняет большую часть времени небольшую, «горячую» часть программы, может власть всё заоптимизировать и закешировать? Иногда, когда такой тип нагрузки встречается в «настольных» приложениях, Java работает вполне сносно, если не считать относительно долгий запуск и повышенные требования к памяти. Но почему-то мало кому приходит в голову писать на Java браузеры, например, или медиа-кодировщики. Хотя, казалось бы, тут Java прямо напрашивается, т.к. сложность проектов зашкаливает. А причина проста — характер нагрузок просто не позволит Hotspot развернуться, ну и память тоже. Хотя, учитывая сколько памяти ест Хром — может даже Java эффективнее с ней работала.
1. Почему в из Hotspot до сих пор не выкинули вообще интерпретатор?Например потому что куски кода, которые отрабатывают всего один раз часто быстрей проинтерпретировать, чем скомпилировать + сохранить + выполнить.
У меня кушается проца 250% и памяти 4 процесса: 370+170+140+150 = 830м.
jvm столько будет жрать на довольно больших программах (например нетбинс жрет около 700m), хром — ест это просто потому, что хочет. И c ff ситуация обстоит примерно так же. Интерпретатор жрет мало, позволяет выбрасывать редкоиспользуемый код, или вовсе не производить его. Поэтому, java жрет по сравнению с подходом «компильнуть вообще все» меньше памяти и меньше проца.
Попробовала бы какая-нибудь idea постоянно 250% кушать. Все бы говорили, что idea тормозит и жрет проц, но для хрома это ок, никому даже в голову не приходит сказать, что это плохо. Всем, кто не жава «разрешено» жрать много.
Java ест столько, сколько дадут. Как и Chrome. С FF ситуация обстоит совершенно не так же.
Черновой компилятор V8 ест мало, работает быстро. Интерпретатор в Java ничего не выкидывает — это делает HotSpot.
Помимо V8 в Chrome есть кому память съесть. Нет никаких доказательств, что подход Chrome хоть чем-то хуже подхода JVM.
Зато есть немало доказательств, что непрогретый Java-код мягко говоря не оптимален — вот, например: https://github.com/floatdrop/v8-vs-java-bench.
Как и вечные жалобы на многочисленные бенчмарки: вы всё врёти! у вас ява не прогрета!
А зачем доказывать, что непрогретый код — неоптимален? И зачем вы мне дали сравнение оптимальности по CPU, если я говорил про лучшую оптимальность по памяти?
То, что непрогретое неоптимально по CPU — это и так известно, но всем плевать на это. Все силы брошены на компилятор — и это правильно. Интерпретатором оракл если и начнет заниматься — то когда совсем нечего будет делать.
Ваш пример, кстати, падает где-то в js после теста с++ и java. То есть, Автор не в состоянии написать непадающий код, и непонимает что он меряет — но уже делает выводы о непригодности и тормознутости технологии, которой пользуются весь мир. Сразу видно — большой специалист.
То, что вы дали — канонический пример непонимания, что вообще происходит, и как работают программы. Там не интерпретатор меряется, а время старта самой vm. Наличие или отсутствие тела у метода main не влияет на конечный результат. (и если починить чтоб не падало, оно скорей всего не будет влиять ни в js ни в ruby ни в python)
Я вас научу правильно отсеивать заведомо плохие тесты. Если видите, что в тесте написано имя java-класса с маленькой буквы — весь тест можно сразу выбрасывать не глядя и не разбираясь. Все равно там что-нибудь сделано неверно, и меряется не то, на что рассчитывает автор.
Читаем изначальный вопрос. Думаем. Догадываемся, что он не про скорость работы, а про скорость чернового компилятора.
Который ни разу много не ест и не тормозит. Тормозит всё потом уже, и память ест потом. Уже когда и основной компилятор отработает, когда кеши заполнятся, когда данные прогрузятся все.
Но при этом даже черновой компилятор V8 в несколько (предположительно) раз быстрее интерпретатора.
И это видно в тех тестах, когда из-за малого количества итераций ни у V8, ни у HotSpot основные компиляторы отработать не успевают: JVM с треском проигрывает.
А что тот тест падает — не удивительно, учитывая дату последнего коммита. И не именно в нём дело.
Про время старта JVM убедительно написано тут, просвещайтесь: http://benchmarksgame.alioth.debian.org/sometimes-people-just-make-up-stuff.html#jvm-startup-time
Вам написали — если выполнять код надо однократно, то быстрей всего его интерпретировать. И по памяти это, очевидно, меньше. «компилятор V8 всех порвет» — это домыслы автора. Что такое интерпретатор в jvm? Это просто switch-case, причем даже слегка заоптимайзеный при помощи таблицы опкодов и goto. Там нету никакой магии. Он не может быть медленней v8-компилятора.
Тогда почему в том тесте померяны тормоза? А вот почему.
Мы уже выяснили выше, что люди, на которых ссылались, не умеют корректно измерять величины, писать тесты производительности, и не понимает, что именно меряют, и почему результаты такие. Это не V8 у него работает быстрей jvm-интерпретатора, а V8 у него стартует и завершается быстрей, чем у него стартует и завершается jvm. Убедится в этом, как я написал выше, можно, убрав тело метода main. На время исполнения всей программы это особо не отразится — что свидетельствует о том, что сама интерпретация тела пренебрежимо мала по сравнению с загрузкой-шатдауном jvm.
Допустим даже v8 хоть в миллион раз быстрей стартует. Лично меня это особо не волнует. Старт jvm все равно визуально-моментален, но мне важно, чтобы потом оно качественно работало, а не поглощало память и проц, как это делает V8.
Кстати, а что не так с датой последнего коммита? Если она старая — оно по-вашему может неработать? Эпично! В java такой фигни нет! :)))
jvm стартует немножко дольше потому, что делает больше действий, которые позволяют ей в будущем работать лучше. Т.е. считайте это уклоном в сторону «медленней компилятор — лучше код». Кроме того, у автора тестов мог быть медленный винт. У java большой рантайм, ~64мб еще и позипован. Медленный винт вполне мог оказать решающую роль. Это действительно не очень хорошо, но масштаб трагедии — понт. Скажем так, хотспот проигрывает — но не с треском, а с потрескиванием головок винчестера. Кстати, ждем девятку, там это должны улучшить, т.к. растащат функционал по модулям. Но все равно, из зипа jvm загружает только то, что реально использует. И все равно, в сколь-нибудь серьезных приложениях значительная часть рантайма используется.
Вообще вы можете запустить HotSpot с флагом -XX:-UseInterpreter
. Вы можете сами потестировать, будет ли ваше приложение работать от этого быстрее. По моим прикидкам обычно интерпретатор медленнее, чем C2-код в 20-100 раз. Разумеется, всегда можно придумать тест, где цифра сильно изменится в любую сторону. Java-таки не для бэкэнда, это универсальный язык программирования.
-XX:-UseInterpreter
не отключает интерпретатор. Для форсированного выполнения скомпилированного кода служит флаг -Xcomp
, который эквивалентен -XX:-UseInterpreter -XX:-BackgroundCompilation -XX:-ClipInlining -XX:Tier3InvokeNotifyFreqLog=0 -XX:Tier4InvocationThreshold=0
Это будет хорошим приближением работы в полностью компилируемом режиме. Но на самом деле, HotSpot не умеет работать вообще без интерпретатора.
Спасибо за поправку! А отдельно -XX:-UseInterpreter
без всего остального что будет значить?
Почему Google в V8 сделала это, а Oracle — нет?Потому что они работают с разными входными данными. V8 нужно в любом случае скомпилировать программу (поступает-то она в виде декста, так что всё равно нужно распарсить этот текст, преобразовать в внутреннее представление и т.д. и т.п.). Можно компилировать в промежуточный байткод, можно — прямо в машинный (по-быстрому, без оптимизаций).
Хотя, учитывая сколько памяти ест Хром — может даже Java эффективнее с ней работалаНе работала бы. Вот прямо сейчас у меня запущено 70 процессов Хрома. Запуск сравнимого числа JVM приведёт к тому, что жалких 8GiB памяти не хватит — даже если там будут крутиться «Hello, World»'ы. Безопасно запускать много процессов в одной JVM — тоже нельзя (Oracle это признал, когда отказался даже от попыток сделать вид, что HostSpot способен обеспечить безопасность, и превратил Java в ActiveX--).
В общем я не знаю ни одной задачи, которую Java обещала бы решить — и при этом успешно решила (только не надо про «умные IDE»: если бы столько денег, сколько вбухали в разработку IDE для Java на Java вбухали бы в IDE на C++ для C++ — результат был бы не хуже).
Я понимаю, и частично разделяю ваш скепсис к скорости работы и потребляемым ресурсам приложений на Java. Но надо признать, что при условии предоставления достаточных объёмов памяти, чего никто не скрывает, оно зачастую работает вполне прилично и быстро.
JIT-компилятор оптимизирует не круто, а очень круто