Hi,

I think there's not much you can do here. The complexity of the test you created is extremely exponential, both in time and in space. Here are the results I get from using another rule engine:

(nb Triples in query, nb Triples in result, execution time in msec)

(2, 3, 0)
(5, 39, 0)
(10, 9901, 46)
(11, 33615, 156)
(12, 116115, 578)
(13, 406627, 2380)
(14, ?, ?)

Here the point at which the memory just can't hold all the objects needed comes at 14, the same will happen to Drools at some point. Or maybe with Drools the first problem encountered will be the time complexity. At some point one of them just has to become to bad for a system to be of any practical use, but that's the case with all exponential problems. I doubt any rule engine will hold its own longer then, say, 20 with this test!

Greets,



Andreas Andreakis wrote:
Hallo,

In order to test the Reasoning performance of the rule engine, I wrote a small performance test.
Using a Triple BeanClass, containing Resource-Property-Object attributes all of them as String,  I defined a rule which does the following:

(X, link, Y) and (Y, link, Z) -> (X, link, Z)


Now I create a specific count of Triples (here 2), which are lineary connected:
(Triple1, link, Triple2)
(Triple2, link, Triple3)

the result I get when I fire the rule and read the Objects is as expected:
(Triple1, link, Triple2)
(Triple2, link, Triple3)
(Triple1, link, Triple3) //<---- new Fact, inferenced one


But currently, the performance is very poor.
If I set 8 Triples (lineryy connected one after another) it takes: 484 ms
9 Triples need: 2156 ms
10 Triples need: 20828 ms (!)


see the attachments for the rules file (rule.xml), the Triple Class and the Main class.


Is there a way to tune the process ? I doing something wrong ?

thanx in advance,
Andreas



package transitivity2;

public class Triple {


  private String resource;

  private String property;

  private String object;


  public String getObject() {

    return this.object;
  }


  public void setObject(String object) {

    this.object = object;
  }


  public String getProperty() {

    return this.property;
  }


  public void setProperty(String property) {

    this.property = property;
  }


  public String getResource() {

    return this.resource;
  }


  public void setResource(String resource) {

    this.resource = resource;
  }


  public String toString() {

    return "<" + resource + "> <" + property + "> <" + object + ">";
  }

}
  

<rule-set name="cheese rules" xmlns="http://drools.org/rules" xmlns:java="http://drools.org/semantics/java" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://drools.org/rules rules.xsd http://drools.org/semantics/java java.xsd"> <import>java.lang.String</import> <import>transitivity2.Triple</import> <rule name="Generic TransLink Rule"> <parameter identifier="X"> <class>transitivity2.Triple</class> </parameter> <parameter identifier="Y"> <class>transitivity2.Triple</class> </parameter> <parameter identifier="linkName"> <class>java.lang.String</class> </parameter> <java:condition>Y.getResource().equals(X.getObject())</java:condition> <java:consequence> Triple newTriple = new Triple(); newTriple.setResource(X.getResource()); newTriple.setProperty(linkName); newTriple.setObject(Y.getObject()); drools.assertObject(newTriple); </java:consequence> </rule> </rule-set>

package transitivity2; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.drools.FactHandle; import org.drools.RuleBase; import org.drools.WorkingMemory; import org.drools.io.RuleBaseLoader; public class Main { /** * @param args */ public static void main(String[] args) throws Exception{ RuleBase base = RuleBaseLoader.loadFromInputStream(Triple.class .getResourceAsStream("rules.xml")); WorkingMemory memory = base.newWorkingMemory(); //set here the linkName String linkName = "subClassOf"; //set here the list depth int triplesCount = 9; List<Triple> tripleList = new ArrayList<Triple>(); for (int i = 1; i <=triplesCount; i++) { Triple t = new Triple(); t.setResource(String.valueOf(i-1)); t.setProperty(linkName); t.setObject(String.valueOf(i)); tripleList.add(t); } // hold time long time = System.currentTimeMillis(); //assert all Triples into WorkingMemory for (Triple t : tripleList) { FactHandle handle = memory.assertObject(t); } memory.assertObject(linkName); memory.fireAllRules(); //Display calculation time: System.out.println("Trans-calculation: "+(System.currentTimeMillis()-time)+" ms"); //Display all Triples. Old + new infered (over transitivity) List objects = memory.getObjects(Triple.class); for (Object object : objects) { Triple currentTriple = (Triple)object; System.out.println(currentTriple); } }//end main }//end class

Reply via email to