Скорость java: Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб» / Хабр

настоящее и будущее / Хабр

Уже два десятилетия активно плодятся мифы о том, что приложениям на Java свойственны проблемы с производительностью. Одновременно с этим на Java создаются по-настоящему высоконагруженные системы. Кто же в конечном итоге прав? Чтобы составить мнение о том, как сейчас обстоят дела с производительностью Java, мы обратились к двум заинтересованным сторонам: создателям самой Java и клиентам, использующим Java в своих системах. На наши вопросы любезно согласились ответить Алексей Шипилёв (Oracle) и Олег Анастасьев (Одноклассники).

Java Performance глазами создателей JDK

JUG.RU: Расскажите, пожалуйста, о себе и о своей работе?

Алексей Шипилёв: Меня зовут Алексей Шипилёв. Я работаю над производительностью Java уже более 10 лет. За это время я успел поработать над разными JVM — сначала над Apache Harmony в Intel, потом перешел в Sun Microsystems, где занимался OpenJDK. На текущий момент моя работа по большей части заключается в том, чтобы находить проблемы производительности в продукте и обозначать пути их решения или же исправлять собственными руками, если проблемы простые. Сюда входит и оптимизация под стандартные бенчмарки, тестирующие производительность виртуальной машины, и решение клиентских проблем (оптимизация их приложений), и улучшение глобальных вещей, которые необходимы многомиллионной экосистеме Java.

JUG.RU: Как вы считаете, корректно ли вообще на сегодняшний день говорить о том, что производительность — проблема в целом Java, как технологии, а не отдельных приложений?

Алексей Шипилёв: Об этом сложно говорить, поскольку производительность чаще определяется всё же кодом конечного приложения, а не задействованным для его создания языком. У языка программирования вообще нет производительности, она может быть только у реализации этого языка. Причем, различных реализаций может быть много. Однако в мире Java случилось так, что чаще всего речь идет о реализации JDK от Sun/Oracle, которая занимает более 95% рынка. Её и будем иметь в виду.

В самом начале, в 1995 — 2000 годах, Java, как и всякий молодой продукт, действительно была не очень эффективно реализована. Но за последнее десятилетие в реализациях Java сделано настолько много, что проблемы, которые раньше считались типичными, перестали так сильно и так больно бить разработчиков по голове.

Конечно, многие сложности, связанные с разработкой высокопроизводительных приложений, сохранились, так что говорить, что эта проблема окончательно решена, по-моему, неосмотрительно. Есть ещё много вещей, которые необходимо докручивать.

Но важно помнить, что далеко не всем нужны высокопроизводительные решения: у многих разработчиков производительность не входит в список критериев успеха — «работает за приемлемое время» и хорошо. Если же разработчикам действительно нужна каждая последняя капля производительности, им придётся обходить подводные камни, которые присутствуют в любом достаточно сложном продукте (а виртуальная машина HotSpot — и OpenJDK в целом — очень сложный продукт).

JUG.RU: Иными словами, производительность уже не является глобальной проблемой Java?

Алексей Шипилёв: Думаю, да.

Честно говоря, мне кажется, что проблемы производительности любой платформы — преувеличены. Как я говорил, большинство приложений не требуют большой производительности. Но в программистском сообществе существуют стойкие легенды и простые рецепты, которые очень удобно повторять (когда ты их повторяешь, кажется, что присоединяешься к группе посвящённых!). И одна из таких легенд заключается в том, что «Java тормозит». Лично я уверен, что она давно не релевантна. Для неё были объективные подтверждения лет 10-15 назад, но сейчас обстановка изменилась. Безусловно, и сейчас можно написать приложения, которые наступят на проблемы с производительностью в рантайме. Но эти проблемы в основном известны, для них есть обходные пути, а те, кому такие пути не подходят, создают собственные «костыли».

JUG.RU: Насколько активно идёт развитие JDK и, соответственно, устранение известных проблем производительности (если говорить об Oracle JDK)?

Алексей Шипилёв: Достаточно активно, и этому есть причина — экосистема Java очень большая, даже в пересчёте на одну компанию. У того же Oracle энтерпрайз-стеки написаны на Java. Соответственно, любое улучшение, которое делается в платформе, распространяется по всему стеку и облегчает жизнь в том числе и разработчикам Oracle. Но это история, почему Oracle развивает OpenJDK. Эта история в разных качествах повторяется и для других вендоров, и для других проектов с открытым кодом.

JUG.RU: Какие последние нововведения в Java вам кажутся наиболее значимыми с точки зрения повышения производительности?

Алексей Шипилёв: Во-первых, мне нравится, что история со сборщиком мусора Garbage-First (G1) потихоньку идет к логическому концу. Garbage-First был анонсирован давно, но только в Java 8 и 9 он стал себя довольно прилично вести, так что его можно использовать в промышленных масштабах — настолько, что в Java 9 он включён по умолчанию. Этот многолетний проект наконец-то выстреливает и делает вещи, которые задумывались с самого начала.

Во-вторых, мне близка история с высокопроизводительными приложениями, которые требуют Unsafe, на замену части которого разрабатывается VarHandles. Есть легитимные случаи, когда хочется выжать последние капли производительности при помощи низкоуровневых хаков. Но Unsafe, как известно, — это приватный API, толком не стандартизированный, т.е. его использование — это бег с острыми ножницами по тлеющим углям горящего здания. А VarHandles — это один из путей, при помощи которого мы можем предоставить публичный API для таких редких, но важных случаев, когда нужна максимальная производительность или какая-то функциональность, которая иначе не доступна.

Еще одно интересное нововведение — Compact Strings. Я лично участвовал в этом проекте и прочих «строковых» оптимизациях. Подобного рода изменения платформы, серьёзно улучшающие общеупотребительные классы, существенно повышают производительность вообще всех приложений, которые написаны на Java, и тем самым ещё больше снижают необходимость костылей.

И в данном случае мы получили очень хороший результат не только на синтетике, но и на реальных приложениях. Достигнутое улучшение занимаемой памяти и производительности на 10% на больших приложениях — это очень хорошие приросты для такой здоровой взрослой платформы, как Java.

JUG.RU: Раз уж мы говорим о производительности, существуют ли какие-то «канонические» методы её измерения? Сводится ли для бизнеса всё к деньгам?

Алексей Шипилёв: Производительность не всегда переводится в деньги. На практике довольно сложно оценить, как прирост производительности влияет на экономическую сторону вопроса. Часто это косвенные эффекты — время, которое тратит программист на написание кода, укладывающегося в цели по производительности; время, которое тратят пользователи на ожидание результата, и т.п. Но с размещением серверов в облаках и плотных датацентрах производительность стала ближе к финансовой стороне вопроса: чем быстрее работает твоё приложение, тем меньше оно потребляет ресурсов, тем меньше ты платишь за аренду и обслуживание серверов. Причем эта зависимость в хорошо масштабируемых приложениях может быть просто линейная, т.е. разогнал на 50% свое приложение — тебе нужно в 2 раза меньше железа, платишь за инфраструктуру в 2 раза меньше.

Кроме того, вопрос денег возникает, когда нужно оправдать временные затраты на оптимизацию. Организации, которые занимаются коммерческой разработкой — не богадельни. Они платят инженерам, чтобы те помогали решать их бизнес-задачи, поэтому организации пытаются понять, стоит ли финансировать конкретное направление разработки; сколько бизнес-профита дадут эти результаты. Так что оптимизация — это не просто «мы тут поковырялись отверточкой, потому что нам очень интересно ковыряться именно здесь». Так могут мыслить отдельные разработчики, иногда удачно соотнося эти желания с бизнес-целями, но бизнес сам по себе в оптимизации ради оптимизации не заинтересован.

JUG.RU: Какие будущие нововведения в JDK, на ваш взгляд, наиболее ожидаемы с точки зрения управления производительностью?

Алексей Шипилёв: Value Types — очень ожидаемое нововведение, которое на данный момент планируется реализовать к выходу Java 10. Это очень сложный проект, который требует подробного разбора, как он стыкуется со всей остальной платформой. «Священная корова» Java — это обратная совместимость. Нельзя сделать фичу, которая её сломает (точнее, можно сломать её в каких-то мелких моментах, но нужно очень хорошее обоснование, почему вы это ломаете, и какие у пользователя есть пути обхода).

Value Types решает очень простую проблему. Одним из столпов Java как языка программирования является негласное свойство, что (практически) всё — объект. В этом кроется интересная грабля: проистекает она из того, что у объектов Java есть индивидуальные свойства. Например, идентичность (identity): если вы сделали объект, у которого записано число 42 в каком-то его поле, и второй объект, в котором лежит «такое же» число 42, то эти 2 объекта — разные с точки зрения языка, и отличаются как раз за счет identity. С точки зрения реализации, это означает, что и хранить нужно две отдельные копии этих практически одинаковых объектов — например, чтобы было где сохранить метаинформацию о них. И когда в приложении появляются большие графы объектов, накладные расходы для каждого объекта пожирают существенную часть полезной памяти. Было бы неплохо, если бы в языке были сущности без identity, для которых этого можно было бы избежать. И такие сущности есть: примитивы! Но их список жёстко зафиксирован. Естественное расширение — дать возможность декларировать сущности, которые записываются как классы, а работают как примитивы — это и есть value types.

Value types существенно отличаются от привычных reference-типов. Например, является ли Object супертипом для всех value-типов? Логично, что нет, и тогда появляются тонкие моменты взаимодействия с дженериками, со специализацией и т.п. Есть библиотеки, которые делают подобного рода специализацию руками (тот же GNU Trove), но всем хочется, чтобы это было реализовано в самом языке. Так что эта очень ожидаемая фича: известно, какие бонусы она принесёт; известно сейчас, какие возникнут проблемы. Однако в ходе разработки мы посмотрим ещё, сколько там реально бонусов, а сколько проблем.

JUG.RU: Учитывая, что проблемы производительности — скорее частные, нежели глобальные, можно ли говорить о какой-то типичной схеме при оптимизации приложений?

Алексей Шипилёв: Существуют вполне конкретные методологии, которые предписывают, куда в первую очередь стоит смотреть на основании тех или иных симптомов. Мы с Сергеем Куксенко и прочими делали доклады на эту тему.

К примеру, можно говорить, что у нас очень хорошие сборщики мусора, но, как ты не крутись, если будешь очень много мусорить, то в итоге сборка мусора будет занимать существенную часть времени. Какой рантайм ты не напиши, а если программист руками написал сортировку пузырьком или линейный поиск по массиву в 100 миллионов элементов, быстро не будет. Тут никакой магии нет — один дурак может такую задачку загадать, на которую семеро мудрецов не ответят.

По моему опыту могу сказать, что если производительностью конкретного приложения никто никогда не занимался или занимался плохо, то там почти наверняка (на 99%) есть множество идиотских или очевидных неэффективностей, которые можно быстро обнаружить и быстро исправить, подняв производительность в разы.

JUG.RU: А кроме сборки мусора какие есть типичные проблемы, легко поддающиеся оптимизации?

Алексей Шипилёв: Мои любимые — проблемы с многопоточностью. Известно, что самый простой способ написать корректное многопоточное приложение — это щедро использовать синхронизацию. Я не говорю, что эта практика порочна,  но часто встречаются проблемы с тем, что аппаратные ресурсы используются не полностью из-за постоянных блокировок. Это очень легко диагностируется, и зачастую легко исправляется (часто, правда, требует правок в архитектуре).

Очень часто встречаются алгоритмические проблемы, когда переписыванием плохих кусочков кода на хорошие кусочки, которые либо имеют лучшую алгоритмическую сложность в принципе, или каким-нибудь способом используют специфичные знания о данных в приложении, получаются гигантские приросты, которые никаким рантаймным оптимизациям и не снились.

JDK/JVM-специфичные проблемы встречаются, но редко. Сюда падают и проблемы с плотностью данных в памяти (откуда нам опять машут рукой value types), и проблемы с высокоуровневыми оптимизациями (escape-анализ и автовекторизация, привет!), и проблемы с кодогенерацией. И тут скользкий вопрос — проблема в том, что рантайм плохой и не работает «правильно», или в том, что мы не хотим в данном случае как-то изменить решение, чтобы у нас была производительность лучше (например, использовать дополнительную библиотеку). Разные люди и разные организации смотрят на это по-разному.

Вообще с моей точки зрения оптимизация производительности Java-приложений принципиально не отличается от оптимизации какого-то нативного приложения, в котором JVM не участвует. JVM — это, конечно, отдельный уровень в этой иерархии, но многие проблемы, которые там существуют, присущи разработке вообще, а не разработке конкретно на Java.

JUG.RU: Учитывая, что определенные проблемы всё же существуют, есть ли смысл использовать Java для высокопроизводительных приложений?

Алексей Шипилёв: Знаете, когда я был школьником, один из моих преподавателей в ответ на ехидный вопрос кого-то из моих друзей, почему же мы не пишем на таком-быстром-С, сказал следующую вещь: «Я буду писать мой промышленный код на Pascal (популярном в те далёкие времена), потому что он везде мне подложит подстилки, везде всё проверит, не даст мне выстрелить себе в ногу. А в том месте, где мне важна скорость, я уж обману его так, чтобы было быстро». И эта история повторяется с разными действующими лицами и с разными языками: Pascal против C, Java против C++, C против ассемблера и т.п. На деле производительность большого приложения на горизонте вменяемых приростов, как правило, определяется производительностью довольно маленького куска в этом приложении. Поэтому может быть проще не буйствовать и не писать на языке, который вас заставляет писать низкоуровневый код, потому что вы с ума сойдете. Стоит писать на высокоуровневом языке, а там, где надо, обмануть его: сделать так, чтобы в конкретных местах было быстрее, перейдя либо к менее идиоматическому коду, повторяющему кривизну библиотек и рантайма, либо отдав тяжёлое на уровень ниже. Практика промышленной разработки на Java и история её производительности во многом этот подход олицетворяет.

Ближайший доклад Алексея состоится на конференции Joker 2016 в формате кейноута и, конечно же, он будет посвящен производительности платформы и способам повышения производительности вашего кода.

Java Performance глазами разработчика

JUG.RU: Расскажите, пожалуйста, о себе и о своей работе.

Олег Анастасьев: Я работаю в команде платформы в компании Одноклассники. Команда платформы разрабатывает программы для того, чтобы Одноклассники работали быстро, т.е. разрабатывает и поддерживает различные хранилища данных, фреймворки для коммуникации серверов друг с другом и т.п. Кроме того, если что-то с быстродействием случается на продакшене, именно команда платформы ищет решение, как это лечить. Наша ответственность — сделать так, чтобы Одноклассники работали быстро, потому что если они не будут работать быстро, они просто работать не будут — очень быстро завалятся под нагрузкой.

JUG.RU: Как вы считаете, есть ли смысл использовать Java для высоконагруженных приложений? Или попросту нет альтернативы?

Олег Анастасьев: Возможно, Java — не самый быстрый язык, существуют и более быстрые языки. Но если рассматривать Java, как язык для разработки больших нагруженных проектов, то здесь ей в принципе альтернатив пока нет. Можно написать более быстрый код на языках C или C++, но при этом этот код будет более дорогой — его написание, отладка и последующая поддержка будут стоить значительно дороже, чем аналогичный код на Java. Кроме того, к коду на C, который торчит в интернет, возникает очень много вопросов безопасности. Как известно, в языке С возможны всякие небезопасные конструкции, через которые потом нехорошие люди будут вас взламывать. На Java таких небезопасных конструкций меньше, поэтому в части безопасности программа на Java потребует меньших усилий.

В итоге Java имеет очень хорошее отношение цена / производительность.

У Java есть ряд проблем, в частности, нам пришлось отдельно работать над управлением памятью и поддержкой высокого трафика, но они могут быть решены при помощи небольшого количества кода — мы для этого создали отдельную библиотеку one-nio (ссылка на https://github.com/odnoklassniki/one-nio). Вся остальная масса кода обладает теми положительными чертами Java, которые у нее есть — быстрая разработка, безопасность, хороший инструментарий диагностирования проблем, встроенный в JVM, защита от ошибок и т. д.

JUG.RU: Вы упомянули, что пришлось решать определенные проблемы производительности. Расскажите, пожалуйста о них подробнее?

Олег Анастасьев: Для нас быстродействие — это не только скорость выполнения  кода на Java. Мы рассматриваем его и с ракурса эффективного использования ресурсов — то есть и объём обрабатываемых данных, и пропускная способность, и потребление памяти. И здесь в Java, действительно, много чего не хватает: коллекций примитивов, struct-ов, работы с оффхипом, прозрачного использования нативных API, управления affinity, файловыми кешами и т.д., поэтому нам приходится разрабатывать решения, которые позволяют обходить узкие места.

Для нас быстродействия Java в такой трактовке не хватает, более того, этот вопрос не может ждать несколько лет следующего релиза Java — проблемы должны решаться прямо сейчас, поэтому мы активно ищем их решения сами. Давайте остановимся на этом подробнее.

Например, одна из болевых точек Java — это быстродействие ввода-вывода, как блокирующего, так и не блокирующего (в частности, сетевого).

Это хорошо видно на примере раздачи видео. Общий исходящий трафик видео сейчас достигает 500 гигабит. Для того чтобы обслуживать такой поток мы должны раздавать видео как можно быстрее, чтобы как можно больше трафика приходилось на один сервер. Наше железо способно отдавать 40 Гбит с машины, но написать на Java при помощи стандартных решений сервер, который будет использовать все 40 Гбит у вас не получится — будет слишком много потерь в производительности внутри самой Java. Это одна из проблем, которые мы решали в составе нашей open source библиотеки.

Пример с 40 Гбитным трафиком — это своего рода экстремум. Есть и менее нагруженные сервера, но там тоже присутствуют свои проблемы. Например, еще одна болевая точка Java — это хранение большого количества объектов в памяти. У Java есть garbage collector. С одной стороны, это хорошо, поскольку он позволяет автоматически убирать мусор. Но с другой стороны, когда вам нужно кешировать в памяти очень много информации, он скорее мешает, чем помогает. Более того, если массив данных на сотню гигабайт хранится в памяти, то вы захотите, чтобы он не потерялся при перезапуске программы — его загрузка займет значительное время. Такие массивы хочется хранить в разделяемой памяти, а встроенных средств в Java для этого тоже нет. В таких местах хочется иметь ручное управление памятью. Хорошо, что в Java есть Unsafe, через который мы и сделали собственное решение.

JUG.RU: Развивается ли JDK в направлении решения специфичных для ваших задач проблем? Появляются ли новые опции, которые вы можете использовать?

Олег Анастасьев: Последняя выпущенная в мир версия Java — 8. В ней решений упомянутых проблем нет. Есть только намерение решить какие-то из этих проблем в Java 9, часть из них — в 10 и более поздних. Но получится или не получится; насколько предложенные решения будут лучше, чем есть сейчас, говорить пока рано, т.к., например Java 9 еще не вышла. Конечно, бета-версию уже можно брать, но что изменится, пока она дойдет до релиза, не известно. Поэтому выйдет Java — посмотрим.

JUG.RU: А есть ли какие-то ожидаемые нововведения, которые могли бы вам помочь? К примеру, VarHandles?

Олег Анастасьев: Поможет или нет нам VarHandles зависит от того, как они в итоге будут реализованы в конечной версии, и как быстро они будут работать.

VarHandles — довольно сложный способ даже с точки зрения API сделать то, что сейчас можно сделать просто и понятно через Unsafe. Это возможность объявить массив в памяти одного типа, а потом читать его, как массив памяти другого типа. Для человека, знакомого с принципами ассемблера или C, это выглядит как обращение по адресу памяти и считывание ячейки памяти, как Long или как Byte, в зависимости от ситуации. Грубо говоря, VarHandles позволяет сделать то же самое, но более сложно (это технически более сложное решение на уровне JDK), но зато он имеет больше защиты от программистов, которые периодически «стреляют себе в ноги».

К тому же, VarHandles решают только один из сценариев использования Unsafe. Но мы используем Unsafe также и совсем для других сценариев (например, для кастомной сериализации или работы с разделяемой памятью), и альтернатив этому раньше Java 10 точно не ожидается.

JUG.RU: На основании чего в вашей компании принимается решение о необходимости работы над производительностью приложений?

Олег Анастасьев: Мы не занимаемся быстродействием ради быстродействия; всегда оцениваем экономический эффект от оптимизации.

Для нас производительность измеряется в количестве денег, которые нужно потратить на железо: сначала на закупку серверов, а затем каждый год на их поддержку в дата-центре. Чем больше быстродействие приложений — тем меньше железа необходимо на ту же задачу, т.е. меньше денег уйдет на его поддержку.

Оптимизация производительности отталкивается от поставленных задач. Можем ли мы позволить себе вот это количество техники для этой конкретной задачи?

К примеру, потратить, условно говоря, год работы высококвалифицированного программиста, чтобы улучшить быстродействие на 0,5%, экономически не эффективно до тех пор, пока у вас не затронуты некой проблемой, допустим, все сервера в дата-центре. Тогда это будет экономически эффективно, и мы будем этим заниматься. Если нет, нам проще купить новых серверов, т.е. решить проблему железом.

Для нас быстродействие — это бизнес-метрика; и она имеет четкое экономическое обоснование. Быстродействие пилится до тех пор, пока оно экономически эффективно.

Несмотря на все вопросы к производительности решений на Java, отрадно видеть, что над этими проблемами идет непрерывная работа, а сама Java, несмотря на все нападки, давно стала промышленным стандартом для масштабных высоконагруженных корпоративных проектов.


Больше интересных докладов, технических, хардкорных, вы найдете в программе Joker 2016. Предлагаем вашему вниманию несколько примеров:

  • Volker Simonis, SAP: HotSpot Internals: Safepoints, NullPointers and StackOverflows.
  • Тагир Валеев, ИСИ СО РАН: Stream API: рекомендации лучших собаководов.
  • Jean-Philippe BEMPEL, Ullink: Low Latency & Mechanical Sympathy: issues and solutions.
  • Владимир Иванов, Oracle: Native код, Off-heap данные и Java.

Программирование на Java обзор, сравнение, лучшие продукты, внедрения, поставщики.

Java — строго типизированный объектно-ориентированный язык программирования, разработанный компанией Sun Microsystems (в последующем приобретённой компанией Oracle). Разработка ведётся сообществом, организованным через Java Community Process, язык и основные реализующие его технологии распространяются по лицензии GPL. Права на торговую марку принадлежат корпорации Oracle.

Приложения Java обычно транслируются в специальный байт-код, поэтому они могут работать на любой компьютерной архитектуре с помощью виртуальной Java-машины. Дата официального выпуска — 23 мая 1995 года. На 2019 год Java — один из самых популярных языков программирования.

Программы на Java транслируются в байт-код Java, выполняемый виртуальной машиной Java (JVM) — программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор.

Достоинством подобного способа выполнения программ является полная независимость байт-кода от операционной системы и оборудования, что позволяет выполнять Java-приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности, в рамках которой исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером), вызывают немедленное прерывание.

Часто к недостаткам концепции виртуальной машины относят снижение производительности. Ряд усовершенствований несколько увеличил скорость выполнения программ на Java:

  • применение технологии трансляции байт-кода в машинный код непосредственно во время работы программы (JIT-технология) с возможностью сохранения версий класса в машинном коде,
  • обширное использование платформенно-ориентированного кода (native-код) в стандартных библиотеках,
  • аппаратные средства, обеспечивающие ускоренную обработку байт-кода (например, технология Jazelle, поддерживаемая некоторыми процессорами архитектуры ARM).

По данным сайта shootout.alioth.debian.org, для семи разных задач время выполнения на Java составляет в среднем в полтора-два раза больше, чем для C/C++, в некоторых случаях Java быстрее, а в отдельных случаях в 7 раз медленнее. С другой стороны, для большинства из них потребление памяти Java-машиной было в 10—30 раз больше, чем программой на C/C++. Также примечательно исследование, проведённое компанией Google, согласно которому отмечается существенно более низкая производительность и бо́льшее потребление памяти в тестовых примерах на Java в сравнении с аналогичными программами на C++.

Идеи, заложенные в концепцию и различные реализации среды виртуальной машины Java, вдохновили множество энтузиастов на расширение перечня языков, которые могли бы быть использованы для создания программ, исполняемых на виртуальной машине. Эти идеи нашли также выражение в спецификации общеязыковой инфраструктуры CLI, заложенной в основу платформы .NET компанией Microsoft.

  • Продукты

  • Сравнение

  • Поставщики

  • Производители

  • FAQ

  • Материалы

Поставщики
Программирование на Java

Eleks

GBR. ..

  • GBR
  • UKR
  • USA

Ardas

FRA…

  • FRA
  • GBR
  • UKR
  • USA

Andersen

DEU…

  • DEU
  • GBR
  • GEO
  • HUN
  • KAZ
  • LTU
  • POL
  • UKR

Echo

CAN. ..

  • CAN
  • GBR
  • UKR
  • USA

LineUp

FRA…

  • FRA
  • ITA
  • POL
  • RUS
  • UKR
  • USA

INSCALE

DNK…

  • DNK
  • MKD
  • MYS
  • PRT
  • UKR

Производители
Программирование на Java

Eleks

GBR. ..

  • GBR
  • UKR
  • USA

Ardas

FRA…

  • FRA
  • GBR
  • UKR
  • USA

Andersen

DEU…

  • DEU
  • GBR
  • GEO
  • HUN
  • KAZ
  • LTU
  • POL
  • UKR

Echo

CAN. ..

  • CAN
  • GBR
  • UKR
  • USA

LineUp

FRA…

  • FRA
  • ITA
  • POL
  • RUS
  • UKR
  • USA

INSCALE

DNK…

  • DNK
  • MKD
  • MYS
  • PRT
  • UKR

F.

A.Q.
Программирование на Java

Что такое технология Java и каково ее применение?

Java представляет собой язык программирования и платформу вычислений, которая была впервые выпущена Sun Microsystems в 1995 г. Существует множество приложений и веб-сайтов, которые не работают при отсутствии установленной Java, и с каждым днем число таких веб-сайтов и приложений увеличивается. Java отличается быстротой, высоким уровнем защиты и надежностью. От портативных компьютеров до центров данных, от игровых консолей до суперкомпьютеров, используемых для научных разработок, от сотовых телефонов до сети Интернет — Java повсюду!

Какова производительность Java?

Программы, написанные на Java, имеют репутацию более медленных и занимающих больше оперативной памяти, чем написанные на языке C. Тем не менее, скорость выполнения программ, написанных на языке Java, была существенно улучшена с выпуском в 1997—1998 годах так называемого JIT-компилятора в версии 1. 1 в дополнение к другим особенностям языка для поддержки лучшего анализа кода (такие, как внутренние классы, класс StringBuffer, упрощённые логические вычисления и так далее). Кроме того, была произведена оптимизация виртуальной машины Java — с 2000 года для этого используется виртуальная машина HotSpot. По состоянию на февраль 2012 года, код Java 7 приблизительно в 1,8 раза медленнее кода, написанного на языке Си.

Некоторые платформы предлагают аппаратную поддержку выполнения для Java. К примеру, микроконтроллеры, выполняющие код Java на аппаратном обеспечении вместо программной JVM, а также основанные на ARM процессоры, которые поддерживают выполнение байткода Java через опцию Jazelle.

Каковы основные возможности Java?

  • Автоматическое управление памятью.
  • Расширенные возможности обработки исключительных ситуаций.
  • Богатый набор средств фильтрации ввода-вывода.
  • Набор стандартных коллекций: массив, список, стек и т. п.
  • Наличие простых средств создания сетевых приложений (в том числе с использованием протокола RMI).
  • Наличие классов, позволяющих выполнять HTTP-запросы и обрабатывать ответы.
  • Встроенные в язык средства создания многопоточных приложений, которые потом были портированы на многие языки (например Python).
  • Унифицированный доступ к базам данных: на уровне отдельных SQL-запросов — на основе JDBC, SQLJ; на уровне концепции объектов, обладающих способностью к хранению в базе данных — на основе Java Data Objects (англ.) и Java Persistence API.
  • Поддержка обобщений (начиная с версии 1.5).
  • Поддержка лямбд, замыканий, встроенные возможности функционального программирования

Вы уверены что хотите удалить ?

Да

Нет

Отчет о производительности Java за 2020 г. | JRebel и XRebel от Perforce

Наш отчет о производительности Java за 2020 год основан на результатах нашего исследования производительности разработчиков Java за 2020 год. В этом опросе мы спросили специалистов по Java-разработке об их технологических предпочтениях, составе команды, производительности приложений, времени повторного развертывания и проблемах, связанных с разработкой микросервисов.

Результаты исследования производительности Java

С появлением DevOps разработчики берут на себя больше ответственности за производительность приложений во время разработки. Фактически, наше исследование показало, что большинство разработчиков теперь несут ответственность за нефункциональные требования к производительности.

В нашем сегменте обзора производительности Java мы рассматриваем детали, связанные с производительностью приложений, в том числе;

  • Распространенные проблемы с производительностью
  • Проверка производительности
  • Проблемы с производительностью достигают рабочей среды
  • Влияние повторного развертывания

Результаты опроса по этим вопросам можно просмотреть ниже. Или, если вы хотите увидеть полный отчет, вы можете нажать кнопку ниже, чтобы просмотреть версию отчета в формате pdf.

Скачать отчет за 2020 г.

Нефункциональные требования к производительности Java

Дни отправки потенциально непроизводительного кода на развертывание прошли — по крайней мере, для половины наших респондентов.

51% респондентов сообщили, что у них есть нефункциональные требования, определенные для производительности в их проекте разработки, а 49% сообщили об обратном.

Это связано с необходимостью разработки микросервисов? Или смещение ответственности за разработку с DevOps? Или это просто новое направление для разработчиков? Несмотря на это, больше разработчиков имеют нефункциональные требования к производительности приложений, чем те, у кого их нет.

Было интересно посмотреть, сколько разработчиков теперь предъявляют нефункциональные требования к производительности. Это может свидетельствовать о том, насколько опытны наши респонденты, но это определенно усиливает тенденцию к тому, что разработчиков просят играть более активную роль в тестировании производительности — независимо от уровня опыта.

— Кертис Джонсон, менеджер по продукту в JRebel

Общие проблемы с производительностью Java

Один из наших любимых вопросов, который мы задаем разработчикам, — о том, где они испытывают проблемы с производительностью. Понимание этого дает нам представление о том, с чем сталкиваются команды разработчиков, когда дело доходит до проблем с производительностью.

Для целей данного исследования мы разделили эти распространенные проблемы с производительностью на шесть категорий:

  • Длительное время отклика приложений
  • Утечки памяти
  • Высокая загрузка ЦП
  • Слишком много открытых подключений
  • Чрезмерные запросы ввода-вывода
  • Прочее

В тех случаях, когда респондент отмечал «Другое», его просили уточнить проблему.

55% респондентов сообщили, что наиболее распространенной проблемой производительности является длительное время отклика приложений. Хотя это и не является неожиданностью, это отмечает постоянную тенденцию для разработчиков. Эта тенденция также согласуется с внедрением микросервисов, что примечательно для разработчиков, рассматривающих возможность перехода на архитектуру.

Следующим по величине было появление утечек памяти у 28% респондентов. Высокая загрузка ЦП стала третьей наиболее распространенной проблемой у 28% респондентов, при этом чрезмерные открытые соединения и запросы ввода-вывода составили 24% и 15% соответственно.

10% респондентов выбрали другое, но не было статистически значимых ответов от тех, кто написал. Неудивительно, что об этом сообщается как о самой большой проблеме с производительностью.

— Кертис Джонсон, менеджер по продукту в JRebel

Проверка требований к производительности Java-приложений

Есть много способов, с помощью которых группы разработчиков Java проверяют требования к производительности приложений. Но для целей этого опроса мы ограничили его пятью различными ответами:

  • Разработчики тестируют это
  • Тесты производительности в CI
  • Ручное специальное обеспечение качества
  • APM находит это в рабочей среде
  • Клиенты сообщают об этом

Количество ответов на этот вопрос превысило один на человека, что показывает нам, что требования к производительности обычно учитываются на протяжении всего жизненного цикла приложения.

70% респондентов сообщили, что разработчики тестировали производительность, а 43% сообщили о тестировании производительности во время непрерывной интеграции.

37 % сообщили, что они проверяют производительность с помощью ручного специального контроля качества, а 32 % сообщили, что используют отчеты клиентов для информирования об успехах своей работы.

Наконец, 10 % респондентов сообщили, что они проверяют производительность с помощью технологии управления производительностью приложений.

Проблемы с производительностью Java достигают производственной среды

Несмотря на возрастающую ответственность разработчиков за тестирование производительности во время разработки, проблемы с производительностью по-прежнему возникают в производственной среде. Наш опрос показал, что более 78% команд имели проблемы, которые были запущены в производство за последние 12 месяцев.

Хотя это не случалось регулярно для большинства респондентов (только 17% сообщили о том, что регулярно сталкивались с проблемами), 62% разработчиков сообщили о проблемах с производительностью, возникающих во время производства.

Счастливое меньшинство, у которого не возникло проблем во время производства, составило 21% от общего числа респондентов.

Влияние перезагрузки и повторного развертывания Java

Не было бы обзора JRebel без вопроса о том, как процесс сборки влияет на разработчиков. В конце концов, наш флагманский продукт JRebel создан для того, чтобы помочь разработчикам пропустить перестроение и повторное развертывание.

Но изучение того, как процесс сборки влияет на разработчиков, может дать нам ценную информацию о причинах, по которым люди используют и не используют JRebel.

Из 231 ответивших на вопрос мы нашли общую тему — медленные процессы сборки негативно сказываются на разработчике и коде.

Среднее время повторного развертывания

Повторное развертывание занимает слишком много времени, независимо от того, сколько времени оно занимает. Но для некоторых разработчиков повторное развертывание может превратиться из раздражения в препятствие развитию.

В этом вопросе опроса мы попросили разработчиков определить время повторного развертывания по шкале от нуля до десяти минут плюс.

Для 32% респондентов наиболее распространенное время повторного развертывания составляло от двух до трех минут. Следующее наиболее частое время повторного развертывания, по мнению 20 % респондентов, составляло до одной минуты на каждое повторное развертывание.

Удивительным для нас было то, что, несмотря на широкое распространение микросервисов, более 48% разработчиков испытывали время перезагрузки более четырех минут.

Возможно, еще более удивительным было то, что более 15% наших респондентов сообщили о времени перезагрузки более десяти минут!

Заключительные мысли

И, как и показатели использования технологии Java, эти проблемы с производительностью растут и меняются по мере того, как новые идеи внедряются в экосистему Java.

В качестве яркого примера возьмем микросервисы, о которых мы подробно поговорим в следующей главе: они полагаются на независимо функционирующие сервисы, которые могут связываться и взаимодействовать с другими сервисами внутри приложения.

Но из-за быстрого прогресса в том, как эти отдельные контейнеры могут взаимодействовать, и, казалось бы, бесконечных комбинаций способов, которыми они могут вызывать проблемы с производительностью по мере усложнения приложения, микросервисы оказались настоящим ящиком Пандоры для новых проблем с производительностью. .

Дополнительные ресурсы

Ищете дополнительную информацию о разработке Java в 2020 году? В нашем полном отчете и сегментах представлены результаты нашего последнего опроса разработчиков Java, а также комментарии наших экспертов по Java.

  • Отчет о производительности Java за 2020 год
  • Веб-семинар о тенденциях развития Java за 2020 год
  • Обзор отчета о производительности Java за 2020 год
  • Отчет о микросервисах Java за 2020 год
  • Отчет о технологиях Java за 2020 год
  • 9 Хотите просмотреть полный отчет? Нажмите кнопку ниже, чтобы получить к нему доступ сейчас.

    СКАЧАТЬ ПОЛНЫЙ ОТЧЕТ ЗА 2020 ГОД

    производительность.

    Действительно ли Java работает медленно?

    Кажется, вы задаете два разных вопроса:

    1. Действительно ли Java работает медленно, и если да, то почему?
    2. Почему Java считается медленным, хотя он быстрее многих альтернатив?

    Первый из них более или менее похож на вопрос «длинной ли веревки». Это сводится к вашему определению «медленно». По сравнению с чистым интерпретатором Java чрезвычайно быстр. По сравнению с другими языками, которые (обычно) компилируются в какой-то байт-код, а затем динамически компилируются в машинный код (например, C# или что-то еще в .NET), Java находится примерно на одном уровне. По сравнению с языками, которые обычно компилируются в чистый машинный код и имеют (часто большие) группы людей, работающие только над улучшением своих оптимизаторов (например, C, C++, Fortran, Ada), Java довольно хорошо справляется с несколько вещей , но в целом, как минимум, несколько медленнее.

    Многое из этого связано в первую очередь с реализацией — в основном, это сводится к тому факту, что пользователь ожидает, пока работает динамический/JIT-компилятор, поэтому, если у вас нет программы, которая выполняется довольно долго, чтобы начать с , трудно оправдать то, что компилятор тратит много времени на сложную оптимизацию. Поэтому большинство компиляторов Java (и C# и т. д.) не прилагают много усилий для действительно сложной оптимизации. Во многих случаях дело не столько в том, какие оптимизации выполняются, сколько в том, где они применяются. Многие задачи оптимизации являются NP-полными, поэтому время, которое они занимают, быстро растет с размером атакуемой проблемы. Один из способов сохранить время в пределах разумного — применять оптимизацию только к чему-то вроде одной функции за раз. Когда компилятор ждет только разработчик, вы можете позволить себе потратить гораздо больше времени и применить ту же самую оптимизацию к гораздо большим частям программы. Точно так же код для некоторых оптимизаций довольно громоздкий (и поэтому может быть довольно большим). Опять же, поскольку пользователь ждет, пока загрузится этот код (а время запуска JVM часто является важным фактором в общем времени), реализация должна сбалансировать время, сэкономленное в одном месте, и потерянное в другом — и учитывая, как мало кода извлекает выгоду из сложной оптимизации, сохранение небольшого размера JVM обычно более выгодно.

    Вторая проблема заключается в том, что с Java вы часто получаете более или менее универсальное решение. Например, для многих Java-разработчиков Swing, по сути, является доступной единственной оконной библиотекой. В чем-то вроде C++ есть буквально десятки оконных библиотек, фреймворков приложений и т. д., каждая из которых имеет свой собственный набор компромиссов между простотой использования и быстрым выполнением, согласованным внешним видом и родным внешним видом и так далее. Единственным камнем преткновения является то, что некоторые из них (например, Qt) могут быть довольно дорогими (по крайней мере, для коммерческого использования).

    В-третьих, большая часть кода, написанного на C++ (и тем более на C), просто устарела и стала более зрелой. Многие из них содержат ядро ​​подпрограмм, написанных десятилетия назад, когда дополнительное время на оптимизацию кода было нормальным, ожидаемым поведением. Это часто имеет реальное преимущество в коде, который меньше и быстрее. C++ (или C) получает признание за небольшой и быстрый код, но на самом деле это в большей степени продукт разработчика и ограничения времени, когда код был написан. В какой-то степени это приводит к самоисполняющемуся пророчеству: когда люди заботятся о скорости, они часто выбирают C++, потому что у него такая репутация. Они тратят дополнительное время и усилия на оптимизацию, и пишется новое поколение быстрого кода на C++.

    Подводя итог, можно сказать, что нормальная реализация Java делает максимальную оптимизацию в лучшем случае проблематичной. Хуже того, там, где Java виден , такие вещи, как оконные инструменты и время запуска JVM, в любом случае часто играют большую роль, чем скорость выполнения самого языка. Во многих случаях C и C++ также получают признание за то, что на самом деле является результатом просто усердной работы над оптимизацией.

    Что касается второго вопроса, я думаю, что это во многом вопрос человеческой природы в действии. Несколько фанатиков делают довольно преувеличенные заявления о том, что Java ослепительно быстр. Кто-нибудь попробует и обнаружит, что запуск даже тривиальной программы занимает несколько секунд, а при запуске она кажется медленной и неуклюжей. Немногие, вероятно, утруждают себя анализом вещей, чтобы понять, что во многом это время запуска JVM и тот факт, что, когда они впервые пробуют что-то, код еще не скомпилирован — часть кода интерпретируется, а некоторые компилируются, пока они ждут. Хуже того, даже когда он работает достаточно быстро, внешний вид обычно кажется большинству пользователей странным и неуклюжим, поэтому даже если бы объективные измерения показывали быстрое время отклика, он все равно казался бы неуклюжим.

    Если их сложить, то получится довольно простая и естественная реакция: Java медленная, уродливая и неповоротливая. Учитывая шумиху о том, что это действительно быстро, существует тенденция слишком остро реагировать и думать о нем как о ужасно медленном, вместо (более точного) «немного медленнее, и это в основном при определенных обстоятельствах».

    This entry was posted in Популярное