www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Ява против Котлина - Часть 2: Байт-код

Дата публикации Oct 3, 2019

Предыдущая частьНачалось с введения в то, как у меня появилась идея сравнить Java и Kotlin. Как упоминалось ранее, этот эксперимент и анализ были частью моей магистерской диссертации в Технологическом университете Познани. Кроме того, будучи обычным разработчиком Android для RSQ Technologies и большим поклонником этих двух языков JVM, я хотел ответить на один из наиболее распространенных вопросов, которые могут быть заданы разработчиками JVM -

Какой язык лучше по производительности - Java или Kotlin?

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

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

Исследовать вопрос

Иконка сделана Freepik изwww.flaticon.com

Как и в предыдущей части, в начале я хочу представить вам мой исследовательский вопрос (на этот раз довольно короткий):

Каковы различия в генерируемом байт-коде, создаваемом обоими языковыми компиляторами?

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

Напоминания

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

Иконка сделана Freepik изwww.flaticon.com

Выбор эталона

Представленные тесты являются частьюТест на знание компьютерного языка, Весь люкс состоит из10 разных задач и алгоритмов решениякоторые реализованы на разных языках для сравнения результатов производительности. Не все тесты были включены в этот эксперимент, они были выбраны на основе двух факторов:

  1. лучшая реализация Java, взятая из репозитория CLBG, должна быть конвертируемой в язык Kotlin
  2. программы должны манипулировать как можно более разнообразными данными

В таблице ниже представлен окончательный список использованных тестов с информацией о большинстве манипулируемых данных.

Таблица 1: Выбранные тесты с информацией о большинстве манипулируемых данных

Реализации

Проанализированные реализации были разделены на три группы:

  1. Java (взято с официальной страницы тестов CLBG)
  2. Kotlin-конвертированныйКонвертер Java в Котлин)
  3. Kotlin-idiomatic (основанный на Kotlin-конвертированной версии с внесенными изменениями, рекомендованнымиКрылатые выражения,Соглашения о кодированиии проверки кода IDEA по умолчанию)

Если вы заинтересованы в более подробной информации о реализации, проверьтеСравнение Java и Kotlin.

Языковая версия

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

Таблица 2: Языковая версия

замечания

  • Языки и их версии меняются во времени. Результаты, представленные в этой статье, могут быть недействительными в будущем, когда будут выпущены новые версии

Орудие труда

Иконка сделана Freepik изwww.flaticon.com

Анализ байт-кода основан наJarScanорудие труда. Упомянутая программа является частьюJITWatchсистема, которая статически анализирует файлы JAR и подсчитывает байты в байт-коде каждого метода. После сканирования файлов jar выдает отчеты в формате CSV. Те.csvрезюме используются для обработки и получения окончательных результатов анализа байт-кода.

СJarScanесть возможность определить, какой пакет в jar-файле нужно проанализировать. Благодаря этой опции нет никакой возможности повлиять на результат пакетами и классами из стандартной библиотеки Java или Kotlin

Если вы заинтересованы в испытании инструмента, я рекомендую ознакомиться со статьей«Статистический анализ байт-кода Core Libs с использованием JarScan»Крис Ньюленд. Это помогло мне понять основы и запустить скрипты JarScan.

Статические метрики

Иконка сделана srip изwww.flaticon.com

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

Счет распределения
Еще один метод изJarScanпозволяет пользователю создавать список распределенных типов для каждого вида инструкции выделения.
Подсчитанные инструкции по распределениюnew, newarray, anewarray, multianewarray,
В итоговом отчете каждая строка содержит три значения - инструкция, тип и количество.

Размеры метода
Последний метод, используемый в анализе байт-кода, называетсяmethodSizeHisto, Производит.csvфайл с двумя данными в строке - размером байт-кода метода и их количеством.
Выходные результаты могут быть использованы для рисования.jarгистограммы размера байт-кода метода файла, которые могут помочь с глубоким анализом проблем производительности.

Полученные результаты

Полный список результатов для каждого теста доступен вхранилище проекта,

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

Таблица 3:инструкцииподсчитать результаты

Счет распределения
В таблице 4 представлены наиболее часто выделяемые классы в каждом бенчмарке и каждой реализации. Список пропускает распределения с менее чем двумя вхождениями.

Таблица 4:распределениеподсчитать результаты

Размеры метода
На рисунке ниже представлены гистограммы размера метода для каждого теста и каждой реализации.

Таблица 5:Размер методагистограмм

Выводы

Приведенные выше диаграммы показывают, что в пяти из шести случаев Котлин производит больше заявлений и создает больше распределений.Сгенерированный Java байт-код имеет больше операторов и распределений только в одном тесте, а именноFannkuch Redux, Исходя из этого, мы можем предположить, что компилятор JVM производит меньше выделений и укорачивает байт-код при компиляции кода Java вместо Kotlin.

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

Гистограммы размера метода, представленные в предыдущем разделе, показывают количество каждого метода в файле байт-кода. В этом случае Kotlin, кажется, производит экстремальные значения чаще. Кодлин-идиоматический код имеет самые высокие размеры метода в трех тестахFasta,Мандельброт,Двоичные Деревьяв то время как код, преобразованный Kotlin, имеет наибольшие размеры методов в остальных тестах -N-Body,Fannkuch Redux,Спектральная Норма,

Анализ количества методов также показывает, что код Kotlin имеет в основном большее количество меньших методов, чем Java. Результаты показывают, что только идиоматическая и конвертированная реализации Kotlin производят более пяти методов одинакового размера.Крис Ньюленд в своей статьепредставляет результаты эксперимента по размеру метода байт-кода JVM, который может помочь в понимании этого исключения. Он приходит к выводу, что большинство методов длиной 5 байтов являются геттерами.
Результаты этого эксперимента позволяют сделать вывод, что увеличение количества методов длиной пять байт, вероятно, связано с автоматической генерацией Kotlin методов получения и установки для полей класса.

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

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

И снова ... каков ответ на вопрос исследования?

Иконка сделана Freepik изwww.flaticon.com

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

Как и в случае с предыдущей метрикой, реализация Java, по-видимому, также производит наименьшее распределение в байт-коде JVM. Большее количество выделений в Java происходит только вFannkuch Reduxбайт-код реализации.

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

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

Это оно!

Иконка сделана Сурангом изwww.flaticon.com

Спасибо за чтение! Эти две статьи обобщают более чем год моей работы над экспериментом с магистерской диссертацией - методология, результаты и выводы, сделанные на их основе. Я очень рад, если вам было интересно, если вы поделились информацией, которая была полезна для вашей работы, или просто побудила вас сделать еще несколько гиков с пониманием JVM.

Важно сказать - этот анализ (как по производительности, так и по байт-коду JVM) не является полным источником правды о различиях между этими двумя языками. Это всего лишь один шаг, который может помочь понять эти различия. Это всегда хорошо, чтобы получить больше данных и знаний об этой области!

И снова, если вы обнаружили какие-либо ошибки или просто хотите поделиться своими мыслями и мнениями о моей работе - обратитесь ко мне в разделе комментариев,щебетилиофициальный Kotlin слабину(Якуб Аниола).

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map