Акцент во всех трёх частях был на изучении поведения и выявлении его причин.
Возможно, вы правы, и от академического изложения пользы для читателя будет больше. Попробую четвёртую задачу разобрать в другом ключе, благо сам текст написан лишь частично.
Не заметил, как у меня во время редактирования пропал кусок разметки с самым интересным результатом работы бенчмарка Vector-with-final-fields vs Vector-with-non-final-fields на JRE 1.8.0_161:
Класс подразумевает наличие состояния (state). Интерфейс — нет.
Да, в Java 8 добавили default-методы и статические методы, а в Java 9 — приватные default-методы и приватные статические методы, но с состоянием это не имеет ничего общего.
Если не ошибаюсь, в C# вошло в моду называть интерфейсы с префиксом I, т.к. этот костыль помогает глядя в код понять, что после : находится класс или интерфейс. А использование implements / extends делает код лучше для восприятия (субъективно).
Ага, я чуть позже про OptimizeStringConcat дописал.
Если же в цепочке попадётся append(long), то оптимизация не отработает — ну, не реализовали почему-то в JDK 8), то есть, будет честный вызов Java кода.
Судя по изменениям в stringopts.cpp в JDK 10/JDK 9 относительно JDK 8, то в новых версиях это по-прежнему не оптимизируется.
Согласен, в этом месте влияние JIT не настолько существенное — выше Андрей apangin намекнул на различия в определении длины строки под long в StringBuilder и StringConcatFactory. apangin, я же правильно понял, что речь об этом?
Касательно корректности рассуждений о производительности с учётом огромного числа эвристик HotSpot'а: задача объяснить наблюдаемое поведение выглядит значительно привлекательнее задачи оценки или сравнения производительности алгоритмов.
Но выбор в пользу первого варианта объяснялся форматом проведения викторины на конференции, когда по ответам можно было быстро отсортировать решения и уже дальше смотреть пояснения к ответам. В следующий раз стоит выбрать детерминированный вариант задач.
За задачи и разбор +1, но делать выводы о производительности по байткоду не совсем корректно, как я показывал в презентации.
Спасибо!
За исключением тех случаев, когда javac генерирует идентичный байткод. :) В остальном согласен, и чем дальше (тот же JEP-280), тем поведение JIT-компилятора становится менее предсказуемым.
В этой же презентации про конкатенацию, кстати, тоже есть. Нельзя бенчмаркать StringBuilder и не упомянуть фичу Хотспота под названием OptimizeStringConcat.
О, точно, я уже под утро заканчивал статью и про OptimizeStringConcat совсем забыл, а это важная штука.
Всегда есть место некоторому допущению. Как, например, при вступлении в брак предполагается, что супруги будут верны друг другу.
Вы просите оценить производительность трёх методов, вот только получается, что их производительность зависит не от того, что написано в них самих, а от подробностей внешних условий, которые вы никак не задаёте, а значит они могут быть произвольными.
Строго говоря, на пути вашего кода на Java к производительности есть по меньшей мере javac, JIT-компилятор, GC, side-эффекты от остальной части JVM, OS, hardware и ещё много чего, о чём я даже не подозреваю. При этом, если вы можете легко рассуждать о влиянии всех этих вещей на итоговую производительность — вы круты.
в чём смысл такой задачи — лично мне неясно
В том же, в чём, например, смысл логических задач — разминка для ума.
Я Java бы выучил только за то,
Что раз написав — используй легко.
Релизы не часто, но верность хранит
И качеству кода, и стилю.
Как часто бывает, когда любой наш коммит
Останется с нами на годы?
Совместимости ради полюбишь и ты,
Друг мой, Java исходные коды.
В продакшене были версии Java 6, 7 и 8. И всегда прекрасно себя чувствовал.
Непривычно было только один раз года 4 назад, когда с проекта на Java 7 перешёл на проект с Java 6: но к отсутствию dimond operator, try-with-resources, multi-catch exception привык быстро (только некоторые наработки пришлось портировать).
Чтобы правильно ответить на задачи нужно было либо знать, либо разобраться (посмотреть исходники, закодить за пять минут наколеночный бенчмарк или спросить у гугла). Никто этого не отрицает.
На одном из стендов вообще был ассемблерный код, эквивалент которого генерит JIT — было б время, поразбирался из интереса. Хотя первая реакция была такой же, как ваша.
Часто вы используете реализации List или наследников PrintStream, отличных от JDK'шных?
К самой викторине нужно относиться как к развлечению, хотя и здесь JIT оставляет нам пространство на подумать.
опубликовал разбор задачи с JBreak: Разбор перформансных задач с JBreak (часть 4).
Throwable.fillInStackTrace
начиная с JDK 9 вовсе убрали из списка интринсиков.Возможно, вы правы, и от академического изложения пользы для читателя будет больше. Попробую четвёртую задачу разобрать в другом ключе, благо сам текст написан лишь частично.
Vector-with-final-fields
vsVector-with-non-final-fields
на JRE 1.8.0_161:Кроме самого факта необычности результата, интересно и то, что на JRE 9.0.4 результат не воспроизводится.
Спасибо sheknitrtch за найденную ошибку!
Интерфейс — нет.
Да, в Java 8 добавили
default
-методы и статические методы, а в Java 9 — приватныеdefault
-методы и приватные статические методы, но с состоянием это не имеет ничего общего.Если не ошибаюсь, в C# вошло в моду называть интерфейсы с префиксом
I
, т.к. этот костыль помогает глядя в код понять, что после:
находится класс или интерфейс. А использование implements / extends делает код лучше для восприятия (субъективно).OptimizeStringConcat
дописал.Судя по изменениям в stringopts.cpp в JDK 10/JDK 9 относительно JDK 8, то в новых версиях это по-прежнему не оптимизируется.
Из нескольких вариантов — этот понравился больше всего (и не только мне).
Но выбор в пользу первого варианта объяснялся форматом проведения викторины на конференции, когда по ответам можно было быстро отсортировать решения и уже дальше смотреть пояснения к ответам. В следующий раз стоит выбрать детерминированный вариант задач.
Спасибо!
За исключением тех случаев, когда javac генерирует идентичный байткод. :) В остальном согласен, и чем дальше (тот же JEP-280), тем поведение JIT-компилятора становится менее предсказуемым.
О, точно, я уже под утро заканчивал статью и про
OptimizeStringConcat
совсем забыл, а это важная штука.Всегда есть место некоторому допущению. Как, например, при вступлении в брак предполагается, что супруги будут верны друг другу.
Строго говоря, на пути вашего кода на Java к производительности есть по меньшей мере javac, JIT-компилятор, GC, side-эффекты от остальной части JVM, OS, hardware и ещё много чего, о чём я даже не подозреваю. При этом, если вы можете легко рассуждать о влиянии всех этих вещей на итоговую производительность — вы круты.
В том же, в чём, например, смысл логических задач — разминка для ума.
Я Java бы выучил только за то,
Что раз написав — используй легко.
Релизы не часто, но верность хранит
И качеству кода, и стилю.
Как часто бывает, когда любой наш коммит
Останется с нами на годы?
Совместимости ради полюбишь и ты,
Друг мой, Java исходные коды.
Вот ваши задачи жду. Сам сходу смог только половину осилить (и то ещё проверить надо!)
Из того, что может (лично меня) побудить перейти на Java 9 — это стандартный годный HTTP-клиент и jshell, но с этим и подождать можно.
В продакшене были версии Java 6, 7 и 8. И всегда прекрасно себя чувствовал.
Непривычно было только один раз года 4 назад, когда с проекта на Java 7 перешёл на проект с Java 6: но к отсутствию dimond operator, try-with-resources, multi-catch exception привык быстро (только некоторые наработки пришлось портировать).
Чтобы правильно ответить на задачи нужно было либо знать, либо разобраться (посмотреть исходники, закодить за пять минут наколеночный бенчмарк или спросить у гугла). Никто этого не отрицает.
На одном из стендов вообще был ассемблерный код, эквивалент которого генерит JIT — было б время, поразбирался из интереса. Хотя первая реакция была такой же, как ваша.
Часто вы используете реализации List или наследников PrintStream, отличных от JDK'шных?
К самой викторине нужно относиться как к развлечению, хотя и здесь JIT оставляет нам пространство на подумать.