В то время как некоторые находят язык Groovy все еще в зачаточном состоянии, другие знают, что сейчас есть Groovy ++, и все они следят за тем, что «++» языка принесет, что некоторые рекламируют как Java ++.
Мне было очень любопытно узнать об этом с тех пор, как первый анонс Groovy ++ был анонсирован в прошлом году (это было так давно? :-)). Первоначальные выпуски, которые вышли, были поддержаны минимальной (нет?) Документацией, и теперь есть вопросы в эфире, как —
- Чего он пытается достичь?
- Чего ждать людям, на что и почему?
- Как это будет работать? Будет ли совместим с моим существующим Groovy код?
Понятно, что документации не хватает, потому что проект Groovy ++ очень, очень новый, но это не помогает. Итак, вместо того, чтобы ждать, пока документация станет доступной, я попытался взглянуть на Groovy ++ и найти ответы на свои вопросы. Вот небольшое описание нескольких вещей, которые я понимаю до сих пор. Я надеюсь, что это полезно для некоторых из вас.
Отказ от ответственности: содержание здесь выражает мое понимание и мнение по этому вопросу и подвержен человеческим ошибкам.
Итак, почему Groovy ++?
В небольшом масштабе, я не затрудняюсь понять, зачем нужен Groovy ++. Я использовал Groovy в течение некоторого времени, и, хотя у него много замечательных функций, каждая функция имеет свою цену. Каждый должен нести стоимость функций, независимо от того, заинтересованы ли они в использовании этой функции или нет.
Чтобы взять очень маленький пример, если у меня есть «1 + 2» в groovy, чтобы позволить все динамизм и гибкость языка, проще говоря, он становится 1.plus (2), где вы можете изменить поведение «плюс» «и заставьте» 1 + 2 «сделать» 2 — 1 «, если хотите, и измените поведение» плюс «столько раз во время выполнения, сколько захотите. Таким образом, то, что в Java равно простой + операции, становится вызовом метода, который проходит различные проверки, чтобы увидеть, было ли изменено поведение метода «сейчас», и указать его текущее определение «+». Все это обходится производительностью, памятью и т. Д., И если даже в моих снах у меня никогда не было намерения переопределить «+», мне все равно пришлось бы нести расходы, связанные с соответствующей инфраструктурой Groovy.
Несмотря на то, что основной продукт всегда прилагает усилия для снижения этих затрат, то, чего сейчас не хватает, — это способ полностью избежать затрат.
На мой взгляд, самое большое преимущество Groovy ++ будет заключаться в том, что он позволит вам соблюсти баланс и избежать затрат на функции, которые вы не хотите использовать — насколько это возможно — поскольку он все еще должен оставаться отличным и не превращаться в Java , Это позволит вам выбрать части вашей программы, где вам нужен весь динамизм, гибкость основного ядра и вы готовы платить за него с точки зрения производительности, а также другие части, где вы можете делать это с меньшей динамичностью, но нуждаетесь в более высокой производительности и большем количестве. проверка времени компиляции.
Картинка, которую я имел в виду в Java-> Groovy-> Groovy ++ во время объявления Groovy ++, была такой:
После небольшого пробуждения теперь оно меняется на:
Мне нравится, где находится Groovy ++, и я жду, когда он станет зрелым и еще больше из проекта.
Что такое Groovy ++?
Q. Это связано со стандартным Groovy?
О. Да, это просто расширение стандартного Groovy. Текущие выпуски Groovy ++ используют раскаленные снимки Groovy 1.8.x под капотами. Таким образом, все, что вы можете сделать на базовом groovy, доступно вам, если вы решите использовать статический компилятор groovy ++ для повышения производительности в любом месте.
Q. Где я могу найти это?
А. Вы можете скачать его здесь
В. Я установил Groovy ++. Как мне начать его использовать?
О. Пополнение groovy ++ для ядра groovy находится в groovypp.jar , который находится в папке lib в вашем каталоге установки. Чтобы начать использовать его, убедитесь, что он находится в classpath, а затем используйте аннотацию @Typed , предоставляемую groovy ++. Вы можете пометить выбранные методы, классы или пакеты как @Typed, и только те, которые статически компилируются groovy ++, в то время как для всего остального используется стандартный groovy.
Q. Как это работает внутри? Как его интеграция с groovy может быть такой простой?
О. Это достигается путем подключения к процессу Groovy — путем определения преобразования AST, которое запускается при использовании аннотации @Typed. Если вы не знакомы с основами этой техники, вам может пригодиться следующая статья — Метапрограммирование во время компиляции — Преобразования AST . Проще говоря, это то, что он делает:
- Он перехватывает процесс компиляции, а затем обрабатывает все методы, выбранные с помощью @Typed — прямо или косвенно, через аннотированные классы / пакеты и выполняет их через более строгие проверки времени компиляции, методы вывода типов и
- Изменяет AST, который генерируется Groovy-компилятором до этой точки, чтобы он выводил байт-код, который менее основан на динамической диспетчеризации и, следовательно, имеет лучшую производительность во время выполнения.
Плюсы и минусы использования Groovy ++
Q. Что я теряю?
A. Поведение метапрограммирования во время выполнения на языке Groovy, поскольку отправка методов становится более прямой и менее динамичной.
Q. Что я не теряю?
О. Большинство функций языка Groovy доступны «как есть» даже с Groovy ++, например —
- Расширения Groovy для классов JDK
- Менее многословная заводная кодировка
- Поддержка таких функций, как категории, миксины, замыкания
- Возможность подключиться к компиляции через преобразования AST
Q. Что я получу?
А. Такие вещи, как:
- Лучшая производительность — за счет меньшего использования динамической отправки.
- Еще менее подробный код — благодаря использованию вывода типов
- Более безопасный код — благодаря более строгим проверкам времени компиляции
Сравнение Groovy / Groovy ++ через несколько примеров
Groovy ++ затрагивает прежде всего две области — производительность и более строгие проверки времени компиляции.
Поскольку изменения, которые он вносит для улучшения производительности, являются в основном внутренними (в генерируемом байт-коде — подробности о котором можно оставить для более поздней публикации), в этом разделе в основном делается попытка показать некоторые основные примеры, где различия более заметны снаружи — дать ощущение более строгих проверок времени компиляции и меньшее использование динамической отправки.
Пример 1: (статическая компиляция)
def addG(x, y) {
x + y
}
@Typed
def addGPP(x, y) {
x + y
}
println addG (2, 3)
println addGPP (2, 3)
В groovy ++ компиляция метода addGPP () завершается неудачно, потому что компилятор не знает статически, какую реализацию plus () вызывать, основываясь на типах параметров (groovy делает доступным ряд реализаций «плюс» и выбирает наиболее подходящую). на основе типов времени выполнения). В этом случае, Groovy ++ компилятор не может выводить типы тоже.
Пример 2: (метапрограммирование во время выполнения)
def addG(x, y) {
x + y
}
@Typed
def addGPP(Integer x, Integer y) {
x + y
}
// override plus to make '+' do multiplication instead
Integer.metaClass.plus = {Integer other -> delegate * other}
// because groovy uses runtime meta-programming to see the modified "+"
assert addG (2, 3) == 6
// because groovy++ does not use runtime meta-programming and instead binds to "+" at compile time
assert addGPP (2, 3) == 5
Пример 3: (Производительность)
Хотя этот пример почти ничего не делает, разница в производительности все еще указывает на направление, в котором работает Groovy ++. Разница в более реалистичном использовании может быть значительно выше.
def addG(x, y) {
x + y
}
@Typed
def addGPP(Integer x, Integer y) {
x + y
}
// override plus to make '+' do multiplication instead
Integer.metaClass.plus = {Integer other -> delegate * other}
def start = System.currentTimeMillis()
(1..1000000).each{
addG(2, 3)
}
def end = System.currentTimeMillis()
println "Groovy took ${end - start} milliseconds" // I got ~= 3.7 seconds
start = System.currentTimeMillis()
(1..1000000).each{
addGPP(2, 3)
}
end = System.currentTimeMillis()
println "Groovy++ took ${end - start} milliseconds" // I got ~= 1.8 seconds
Это всего лишь несколько очень простых примеров, чтобы подчеркнуть некоторые различия, обсуждаемые в этой статье. Я постараюсь охватить несколько более сложных примеров и более подробную информацию о Groovy ++ в следующих статьях.
Вывод
Я надеюсь, что статья послужила своей цели, познакомив с Groovy ++ и немного подогревая аппетит. Я чувствую, что Groovy ++ очень хорошо позиционируется между Java и Groovy, и я надеюсь, что он сможет удачно установить магический баланс и помочь Groovy стать еще более популярным языком.