Заставить Groovy использовать стандартный переключатель Java?

У меня есть Groovy switch, вызываемый (очень) часто в моем приложении. Выборка VisualVM показывает, что я провожу около 20 % времени приложения в ScriptBytecodeAdapter.isCase().

Поскольку все случаи являются строками, мое использование будет поддерживаться стандартным Java 7 переключатель строк, который должен быть более эффективным.

Можно ли попросить Groovy вернуться к стандартному переключателю Java?

Примечания:

  • Я могу использовать AST (сам переключатель генерируется AST в SEMANTIC_ANALYSIS).

  • Другие варианты реализации могут заключаться в использовании вместо этого ifs/else (у меня обычно ‹ 20 случаев) или карты замыканий.


person Benoît    schedule 24.05.2016    source источник
comment
Вы пробовали другие варианты реализации и профилировали их, чтобы увидеть, имеет ли это значение? Если это не поможет, вы можете попробовать применить преобразование CompileStatic в своем преобразователе AST (при условии, что это ваш код) - не уверен, что он будет делать то, что вы хотите, но может приблизиться. Помимо этого, есть ли шанс, что вы могли бы просто написать этот класс на Java?   -  person cjstehno    schedule 24.05.2016
comment
Я не пробовал эти другие реализации (я буду, только если переключатель java 7 не вариант). Я добавляю аннотацию CompileStatic к AST, но я не проверял, действительно ли она была учтена... Подойдет.   -  person Benoît    schedule 24.05.2016
comment
Вы находитесь в трудном положении. Да, вы можете повысить производительность, перейдя на стандартную Java, но, к сожалению, язык не всегда дает вам прямой путь к базовой Java. Удачи. Кроме того, убедитесь, что вы применяете CompileStatic к сгенерированному коду программно, а не просто добавляете его как аннотацию к самому преобразователю. ;-)   -  person cjstehno    schedule 24.05.2016
comment
@cjstehno Действительно, кажется, что добавление аннотации в мой AST не говорит компилятору статически компилировать код. Как я могу сгенерировать статически скомпилированный код в своем AST: final MethodNode method = classNode.addMethod(methodName, Modifier.PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] { attNameParam, valueParam }, ClassNode.EMPTY_ARRAY, code); method.addAnnotation (новый AnnotationNode (compileStaticCN)); // кажется бесполезным   -  person Benoît    schedule 24.05.2016
comment
Вы создадите свои узлы кода, а затем примените статический преобразователь компиляции к коду программно.   -  person cjstehno    schedule 24.05.2016
comment
Действительно, проблема заключалась в том, что CompileStatic не применялся. Непосредственное применение StaticCompileTransformation из моего AST решило проблему, и я больше не вижу isCase в своей выборке VisualVM. По крайней мере, не высокий. Спасибо @cjstehno за замечание.   -  person Benoît    schedule 25.05.2016
comment
Я блуждаю, почему ASTTransformationCollectorCodeVisitor не повторно сканирует дерево на каждой фазе, но это был бы другой вопрос...   -  person Benoît    schedule 25.05.2016
comment
Рад, что это помогло. Я преобразовал это в ответ, если вы хотите его принять. :-)   -  person cjstehno    schedule 25.05.2016


Ответы (1)


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

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

Это должно, по крайней мере, сделать еще один шаг вперед.

person cjstehno    schedule 25.05.2016
comment
К сожалению, это не дошло до конца: применение CompileStatic было полезно, так как удаляло некоторые вызовы callXXX, но сгенерированный байт-код по-прежнему использует вызовы isCase, а не мощный переключатель java 7 :-( - person Benoît; 26.05.2016
comment
Я реорганизовал свой AST, чтобы использовать операторы if/else (а не switch/case). Было бы лучше сгенерировать tableswitch, но так как у нас обычно меньше 10-20 случаев, if/else достаточно эффективны. - person Benoît; 26.05.2016