Проблема с производительностью при перечислении утверждений предполагаемой модели
Я занимаюсь разработкой приложения с использованием Apache Jena для работы с тройками RDF и онтологиями OWL.
Эта проблема
То, что я сейчас пытаюсь сделать, это получить модель из тройного магазина TDB, сделать вывод об этой модели и найти некоторые утверждения в предполагаемой модели. Это сделано благодаря StmtIterator listStatements(Resource s, Property p, RDFNode o)
метод. И тогда действительно просто while(iter.hasNext())
цикл сделан для перебора операторов.
На первый взгляд кажется, что он работает хорошо, но очень медленно. Для моей достаточно маленькой модели это занимает около 5 минут, а для модели (не предполагаемой) - всего несколько миллисекунд.
Пример с онтологией Pizza
В этом примере я использую онтологию Pizza, доступную здесь. Код выглядит так:
public class TestInferedModel {
private static final String INPUT_FILE_NAME = "path/to/file";
private static final String URI = "http://www.co-ode.org/ontologies/pizza/pizza.owl#";
private static final Logger logger = Logger.getLogger(TestInferedModel.class);
public static void main(String[] args) {
Model model = ModelFactory.createOntologyModel();
model.read(INPUT_FILE_NAME);
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner = reasoner.bindSchema(model);
Model infmodel = ModelFactory.createInfModel(reasoner, model);
logger.debug("Model size : " + model.size() + " and inferred model size : " + infmodel.size());
// prints Model size : 2028 and inferred model size : 4881
StmtIterator iter = infmodel.listStatements();
while (iter.hasNext()) { // <----- Performance issue seems to come from this line
// Operations with the next statement
Statement stmt = iter.nextStatement();
logger.info(stmt);
}
model.close();
}
}
Здесь размер модели составляет примерно две тысячи троек, а предполагаемая модель состоит из чуть менее пяти тысяч троек. Однако выполнение приведенного выше кода занимает гораздо больше времени, чем выполнение того же фрагмента кода после редактирования. StmtIterator iter = infmodel.listStatements();
в StmtIterator iter = model.listStatements();
, Кроме того, при попытке добавить параметры, ограничивающие операторы, программа работает в бесконечном цикле.
Я попытался добавить пару logger.debug()
сообщение, чтобы увидеть, где программа тратит так много времени, и кажется, что проблема исходит от while(iter.hasNext())
линия.
Вопрос
Я думал listStatements()
метод полиномиальной (или линейной) сложности, а не экспоненциальный, не так ли? Это нормально, что для такой модели требуется так много времени? Как я могу избежать этого?
Я хотел бы иметь возможность составить список утверждений и манипулировать выведенной моделью, не требуя, чтобы пользователь ждал ответа десять минут...
Эта проблема кажется похожей на эту. Однако ответ на самом деле не помогает мне понять.