降低Jena函数的性能“ResultSetFactory.copyResults()”

时间:2017-06-07 13:15:07

标签: performance sparql jena owl

我使用SPARQL查询我的本体,但我观察到性能下降,我请求的查询越多,它就越糟糕。一开始PC需要大约150ms来处理查询,30查询需要670ms,而查询需要超过7秒! 它取决于查询和/或本体,但直到现在,我都可以在每个本体中找到它。

“ResultSetRewindable r = ResultSetFactory.copyResults(results);”负责时间泄漏,但也通过避免线路导致类似的行为来解决。

我使用了披萨本体(https://ontohub.org/pizza/pizza.owl)和以下代码。另外,我使用了Jena 2.13版。

有人知道如何解决它吗?

public static void main(String[] args) throws UnsupportedEncodingException, InterruptedException{
    OntModel model = ModelFactory.createOntologyModel();
    String OWLPath = "pizza.owl";
    String queryString = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX pz: <http://www.co-ode.org/ontologies/pizza/pizza.owl#> SELECT DISTINCT ?x WHERE {     ?b owl:someValuesFrom pz:MozzarellaTopping. ?x rdfs:subClassOf ?b.      ?x rdfs:subClassOf* pz:Pizza.}";
    for(int j=0; j<100;j++){
    double starttime = System.currentTimeMillis();
                InputStream in = FileManager.get().open(OWLPath);
        if (in == null) {
            throw new IllegalArgumentException("File: " + OWLPath + " not found");
        }
        model.read(in, "");

        Query query = QueryFactory.create(queryString);
        QueryExecution qe = QueryExecutionFactory.create(query, model);
        ResultSet results = qe.execSelect();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();   
        PrintStream ps = new PrintStream(baos);

        double time1 = System.currentTimeMillis();
        ResultSetRewindable r = ResultSetFactory.copyResults(results);
        double time2 = System.currentTimeMillis();  

        ResultSetFormatter.out(ps, r, query);
        String queryOutput = new String(baos.toByteArray(), "UTF-8");
        String[] resultText = queryOutput.split("\n");  
        for(int i=0; i<resultText.length;i++){
            System.out.println(resultText[i]);
        }
    double endtime = System.currentTimeMillis();
    System.out.println("Time: "+ (endtime-starttime) +"     Time for ResultSetFactory.copyResults(results): "+ (time2-time1));
    }
 }

1 个答案:

答案 0 :(得分:5)

这是一个简单的错误。问题是模型没有被清理,每次读取本体时,模型都会增加。 该模型可以清理:

model.removeAll();

model.read(in, "");

可以替换

Model model = ModelFactory.createDefaultModel().read(in, "");

它在版本2.13和3.3.0中没有任何问题。此外,所需时间减少了5倍,因此性能更好,更稳定。第二个版本只比第一个版本略好。