Эффективное связывание формулы во время выполнения

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

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

  • производительность: реальные данные часто меняются, таблицы могут быть большими, а формулы сложными, поэтому производительность и использование ЦП являются проблемой.
  • простота конфигурирования (при условии, что конфигурация выполняется разработчиком, поэтому она может включать программирование)
  • ремонтопригодность конфигурации

Подходы, которые я предусмотрел до сих пор:

  1. использовать API Java Scripting, но я бы предпочел использовать подход на основе JVM для повышения производительности
  2. создать interface Formula { double calculate(); } и генерировать, компилировать и загружать реализации во время выполнения - это позволяет JIT компилировать сгенерированные методы
  3. то же самое, что и 2, но с использованием другого языка на основе JVM, такого как clojure, который позволяет легко компилировать на лету и имеет хорошо подходящий функциональный подход (например, карта / уменьшение поможет для вычисления средней и суммы ниже) - не уверен о последствиях производительности, хотя.

Какой подход будет иметь больше смысла? Есть ли другие решения или библиотеки, которые я должен рассмотреть?


пример

Чтобы прояснить цель, вот надуманный пример - давайте предположим, что элементы в таблице:

public class Item() {
    public String category;
    public String name;
    public int quantity;
    public double price;
}

Целевой выход

Category     Name        Quantity    Price (avg)     Value (sum)
All                                      82            1,090

Bikes                                    45              650
             Bike 1         10           40              400
             Bike 2          5           50              250

Cars                                    120              440
             Car 1           3          100              300
             Car 2           1          140              140

Конфигурация столбцов

Столбцы могут быть определены следующим образом:

Column #      Formula
    1         item.name;
    2         item.quantity;
    3         item.price;
    4         Math.abs(column_2 * column_3); //calls a JDK method

Конфигурация агрегации

И категории агрегации и итоговые формулы могут быть определены следующим образом:

AGGREGATION #1: Category cat = item.category();
Column #      Formula
    1         cat;
    2         "";
    3         thisColumn.filter(cat).items().average(); //utility method
    //this one is more complex
    4         { double sum = 0;
                for (double value : thisColumn.filter(cat).items())
                    sum += value;
                return sum;
              }

1 ответ

Я бы использовал пользовательский язык, специфичный для домена, который могут использовать ваши пользователи, и позволил бы ANTLR генерировать собственный анализатор в Java, который анализирует выражение для исполняемой функции.

См., Например, http://arcanecoder.blogspot.be/2008/04/using-antlr-to-create-excel-like.html для примера, который сделал что-то подобное, или http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator для более свежего.

Вы можете определить такие функции, как "сумма", "среднее" и т. Д., Сопоставить их с пользовательским кодом Java и использовать, например, $1 или ${имя}, чтобы они могли ссылаться на свойства.

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

Другие вопросы по тегам