У меня есть много истинных/ложных результатов, сохраненных в виде битов в массивах 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[]), либо узел не является листом и, следовательно, ссылается на несколько подузлов.
Они просты, но позволяют выражать сложные логические выражения. Это прекрасно работает.
Пока все хорошо, все работает отлично. Однако у меня есть проблема: мне нужно оценить МНОГО выражений, определяя, истинны они или ложны. По сути, мне нужно выполнить некоторые вычисления методом грубой силы для проблемы, для которой нет лучшего решения, чем грубая сила.
Поэтому мне нужно пройтись по дереву и ответить либо true
, либо false
в зависимости от содержимого дерева и содержимого long[]
.
Метод, который мне нужно оптимизировать, выглядит так:
boolean solve( Node node, long[] trueorfalse ) {
...
}
где при первом вызове node
является корневым узлом, а затем, очевидно, подузлами (будучи рекурсивным, этот метод solve
вызывает сам себя).
Зная, что у меня будет всего несколько деревьев (может быть, до сотни или около того), но миллионы и миллионы long[]
нужно проверить, какие шаги я могу предпринять, чтобы оптимизировать это?
Очевидное рекурсивное решение передает параметры ((sub)tree и long[], я мог бы избавиться от long[]
, не передавая его в качестве параметра) и довольно медленно со всеми рекурсивными вызовами и т. д. Мне нужно проверить, какой оператор используется (И, или ИЛИ, или НЕ и т. д.), и задействовано довольно много операторов if/else или switch.
Я не ищу другого алгоритма (их нет), поэтому я не ищу перехода от O (x) к O (y), где y будет меньше x.
Я ищу ускорение в х раз: если я смогу написать код, работающий в 5 раз быстрее, то у меня будет 5-кратное ускорение, и это все, и я буду очень доволен этим.
Единственное улучшение, которое я вижу на данный момент — и я думаю, что это будет огромное ускорение в х» по сравнению с тем, что у меня есть сейчас, — будет генерировать байт-код для каждого дерева и иметь логику для каждого дерева, жестко закодированного в класс. Это должно работать хорошо, потому что у меня когда-либо будет только сотня или около того деревьев (но деревья не фиксированы: я не могу знать заранее, как будут выглядеть деревья, иначе было бы тривиально просто жестко вручную закодировать каждое дерево). ).
Любая идея, кроме создания байт-кода для каждого дерева?
Теперь, если я хочу попробовать маршрут генерации байт-кода, как мне это сделать?