Hello,
I am a new Jena developer. I have a probably simple speed question.
Below is a very simple Jena/ARQ program. It is a toy standalone
program that builds a database of 10,000 trees describing families
(dad, mom, kids...), and then does various queries.
The queries are very simple (e.g. families where dad=="Peter"), but
the program runs *very* slowly. Typical queries take 40 seconds on my
AMD 64 box.
Is there something simple I should be doing (or not doing) to make
this run at a reasonable speed?
Thank you
Peter Wolf
import java.util.ArrayList;
import java.util.List;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.query.StageElement;
import com.hp.hpl.jena.n3.N3Exception;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryParseException;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.ModelGraphInterface;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.itasoftware.ndl.know.KnowledgeGraph;
import com.itasoftware.ndl.know.graph.GraphException;
import com.itasoftware.ndl.know.query.Binding;
public class JenaSpeedTest {
/**
* neighborhood --> family *
*
* family --> id, dad, mom, child *, pet *
*
* dad --> person mom --> person child --> person pet --> animal
*
* person --> name age hairColor animal --> name age breed
*/
Model model;
Property id;
Property dad;
Property mom;
Property child;
Property pet;
Property name;
Property age;
Property hair;
Property breed;
int treeCount = 10000;
void printProperty(Property p) {
System.out.println(p + " = " + p.getNameSpace() + " + "
+ p.getLocalName());
}
JenaSpeedTest() {
model = ModelFactory.createDefaultModel();
id = model.createProperty("http://id");
dad = model.createProperty("http://dad");
mom = model.createProperty("http://mom");
child = model.createProperty("http://child");
pet = model.createProperty("http://pet");
name = model.createProperty("http://name");
age = model.createProperty("http://age");
hair = model.createProperty("http://hair");
breed = model.createProperty("http://breed");
//printProperty(pet);
long before = System.currentTimeMillis();
for (int i = 0; i < treeCount; i++)
addFamily(i);
long then = System.currentTimeMillis();
// model.write( System.out,"N-TRIPLE" ); //"RDF/XML-ABBREV" );
// System.out.println(model);
System.out.println((then - before) + " ms to create " + treeCount
+ " trees");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. " + "}");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. "
+ "?family <http://mom> [ <http://name> \"Robin\" ]. " + "}");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. "
+ "?family <http://mom> [ <http://name> \"Robin\" ]. "
+ "?family <http://pet> [ <http://name> \"Toller\" ]. " + "}");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. " + "}");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. "
+ "?family <http://mom> [ <http://name> \"Robin\" ]. " + "}");
timeQuery("SELECT ?id WHERE { ?family <http://id> ?id . "
+ "?family <http://dad> [ <http://name> \"Peter\" ]. "
+ "?family <http://mom> [ <http://name> \"Robin\" ]. "
+ "?family <http://pet> [ <http://name> \"Toller\" ]. " + "}");
Node n;
}
void timeQuery(String query) {
System.out.println("Timing Query:\n" + query);
startTiming();
ResultSet results = doQuery(query);
stopTiming("doQuery");
ArrayList cache = new ArrayList();
startTiming();
while (results.hasNext()) {
cache.add(results.nextSolution());
}
stopTiming("nextSolution");
System.out.println(cache.size() + " results");
}
long then;
long now;
void startTiming() {
then = System.currentTimeMillis();
}
void stopTiming(String name) {
now = System.currentTimeMillis();
System.out.println(name + ": " +
(now - then) + " ms");
}
void addFamily(int i) {
Property family = model.createProperty("http://family" + i);
model.add(family, id, Integer.toString(i));
model.add(family, dad, addDad(i));
model.add(family, mom, addMom(i));
for (int j = 0; j < random(5); j++) {
model.add(family, child, addChild(i, j));
}
for (int j = 0; j < random(5); j++) {
model.add(family, pet, addPet(i, j));
}
}
String[] dads = { "Peter", "Justin", "John", "Frank", "Jeremy" };
String[] moms = { "Robin", "Eleanor", "Liz", "Amy", "Leslie" };
String[] children = { "Jeremy", "Eleanor", "Liam", "Catherine", "Liam",
"Susan" };
String[] hairs = { "Black", "Blond", "Brown", "Red", "Bald" };
String[] breeds = { "Toller", "Beagle", "Mutt", "Tabby", "Siamese",
"Lynx" };
int random(int n) {
return (int) (Math.random() * n);
}
String random(String[] names) {
int i = random(names.length);
return names[i];
}
Property addDad(int i) {
Property pa = model.createProperty("http://dad" + i);
model.add(pa, name, random(dads));
model.add(pa, hair, random(hairs));
model.add(pa, age, 30 + random(30));
return pa;
}
Property addMom(int i) {
Property ma = model.createProperty("http://mom" + i);
model.add(ma, name, random(moms));
model.add(ma, hair, random(hairs));
model.add(ma, age, 30 + random(30));
return ma;
}
Property addChild(int i, int j) {
Property ta = model.createProperty("http://child" + i + "x" + j);
model.add(ta, name, random(children));
model.add(ta, hair, random(hairs));
model.add(ta, age, random(20));
return ta;
}
Property addPet(int i, int j) {
Property ta = model.createProperty("http://pet" + i + "x" + j);
model.add(ta, breed, random(breeds));
model.add(ta, age, random(15));
return ta;
}
private ResultSet doQuery(String query) {
QueryExecution qexec = null;
try {
qexec = QueryExecutionFactory.create(query, model);
return qexec.execSelect();
} catch (QueryParseException e) {
throw new Error("Problem parsing query:\n" + query, e);
} catch (Exception e) {
throw new Error(
"Something went wrong while executing SELECT query", e);
}
}
public static void main(String[] args) {
new JenaSpeedTest();
}
}