У меня есть много истинных / ложных результатов, сохраненных как биты в long[]
массивах. У меня их огромное количество (миллионы и миллионы длинных).
Например, скажем, у меня есть только пять результатов, у меня было бы:
+----- condition 5 is true
|
|+---- condition 4 is false
||
||+--- condition 3 is true
|||
|||+-- condition 2 is true
||||
||||+- condition 1 is false
10110
У меня также есть несколько деревьев, представляющих такие выражения, как:
condition1 AND (condition2 OR (condition3 AND condition 4))
Деревья очень простые, но очень длинные. Они в основном выглядят так (ниже приведено упрощение, просто чтобы показать, что у меня есть):
class Node {
int operator();
List<Node> nodes;
int conditionNumber();
}
По существу, либо узел является листом, а затем имеет номер условия (соответствует одному из битов в массивах long []), либо узел не является листом и, следовательно, ссылается на несколько подузлов.
Они просты, но позволяют выражать сложные логические выражения. Отлично работает.
Пока все хорошо, все работает отлично. Однако у меня есть проблема: мне нужно оценить LOT выражений, чтобы определить, являются ли они истинными или ложными. По сути, мне нужно выполнить некоторые грубые вычисления для задачи, для которой нет лучшего решения, чем грубое принуждение.
Поэтому мне нужно пройтись по дереву и ответить либо true
, либо false
, в зависимости от содержимого дерева и содержимого long[]
.
Метод, который мне нужно оптимизировать, выглядит следующим образом:
boolean solve( Node node, long[] trueorfalse ) {
...
}
где при первом вызове node
является корневым узлом, а затем, очевидно, подузлами (будучи рекурсивным, метод solve
вызывает сам себя).
Зная, что у меня будет только несколько деревьев (может быть, до ста или около того), но миллионы и миллионы long[]
, чтобы проверить, какие шаги я могу предпринять, чтобы оптимизировать это?
Очевидное рекурсивное решение передает параметры (дерево (sub) и long [], я мог бы избавиться от long[]
, не передавая его в качестве параметра), и довольно медленно для всех рекурсивных вызовов и т. Д. I нужно проверить, какой оператор используется (И или ИЛИ или НЕ и т. д.), и в нем достаточно много операторов if / else или switch.
Я не ищу другой алгоритм (его нет), поэтому я не ищу перехода от O (x) к O (y), где y будет меньше, чем x.
То, что я ищу, это "х раз" ускорение: если я смогу написать код, выполняющий в 5 раз быстрее, то у меня будет 5-кратное ускорение и все, и я буду очень доволен это.
Единственное улучшение, которое я вижу на данный момент - и я думаю, что это будет огромное "х раз" ускорение по сравнению с тем, что у меня есть сейчас - будет генерировать байт-код для каждого дерева и иметь логика для каждого дерева жестко закодирована в класс. Это должно работать хорошо, потому что у меня будет только сто или около того деревьев (но деревья не исправлены: я не могу знать заранее, как будут выглядеть деревья, иначе было бы тривиально просто жестко закодировать каждое дерево вручную). ).
Есть идеи, кроме генерации байт-кода для каждого дерева?
Теперь, если я хочу попробовать маршрут генерации байт-кода, как мне это сделать?