Как стать автором
Обновить

Комментарии 18

>8. Groovy
>Всё просто и всё работает, но медленно

Насколько я помню, вы взяли не тот API. GroovyShell — это совсем не способ вычислить выражение. Выражение — это groovy.util.Eval, если мне опять же не изменяет память.

Ну и… вы почему-то пропустили языки, которые поддерживают JSR 223, причем все кроме одного (а их было несколько десятков).
Внутри в Eval тот же самый GroovyShell

Вы правы, можно было все имплементации JSR 223 пробывать, но мне показалось, что у evalEx такое преимущество, что уже и смысла нет
>Внутри в Eval тот же самый GroovyShell

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

 public static Object xy(final Object x, final Object y, final String expression) throws CompilationFailedException {
        Binding b = new Binding();
        b.setVariable("x", x);
        b.setVariable("y", y);
        GroovyShell sh = new GroovyShell(b);
        return sh.evaluate(expression);
    }
Да, вы правы. Я видимо попутал с org.codehaus.groovy.tools.shell.Main, который тоже в некотором роде шелл, но другой.
Сделал, компиляцию выражения таким образом смог вынести и время сильно уменьшилось!
Спасибо
val template = groovy.text.GStringTemplateEngine().createTemplate(expr)

 fun groovyEvaluate(a: Double, b: Double, c: Double): Boolean {
        val binding = HashMap<String, Double>()
        binding.put("a", a)
        binding.put("b", b)
        binding.put("c", c)

        val template = template.make(binding)
        return template.toString().toBoolean()
    }
Вы забыли поменять суммарную таблицу в начале статьи
Сделал!

Хочу обратить внимание, что через ScriptEngineManager можно запускать и целый Котлин (смотреть про kotlin-scripts-utils). Работает шустро, но долго компилируется перед запуском — для случайных выражений долго, а для более-менее постоянных скриптов может быть и интересно.

в 2018 результатам микробенчмарков без использования jmh никто не поверит :)
А ещё есть jexl, который отлично справляется с задачей:
JexlEngine jexl = new JexlBuilder().create();

String jexlExp = "a>10 && b<c+5 && (a+b)<c*4";
JexlExpression e = jexl.createExpression(jexlExp);

JexlContext jc = new MapContext();
jc.set("a", 1);
jc.set("b", 2L);
jc.set("c", 3D);

Object o = e.evaluate(jc);
System.out.println("result: " + o);
Ну так и mvel тоже забыли. Который вообще говоря ровно для этого, и которому много лет, и он успешно применяется в camel, drools и много где еще. И ognl кстати.
Спасибо, попробую
Спасибо! Попробывал — очень хороший результат
у меня на проекте используется старый добрый EL 2.0, но можно попробовать и EL 3.0
пример для 3.0 illegalargumentexception.blogspot.ca/2008/04/java-using-el-outside-j2ee.html

Тут есть список альтернатив stackoverflow.com/questions/17026863
Все собираюсь написать для них benchmark
Есть еще janino который можно как раз использовать как для выражений, так и для java компиляции с помощью ejc. В проекте реализовано много полезного для JSR 199 и т.п.
Я использую JEL
Он компилирует выражения в джава класс, поэтому, теоретически, дает максимальную производительность
Наилучших результатов с ним можно добиться если делать резолвинг переменных не по имени в мепе, а по индексу в массиве
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории