I’ve a use case where I need to create a rule dynamically for a single time use only. The rules are dynamic and in the worse case can be different for each iteration/request. Hence, I cannot store them.
My current understanding of Drools is that you need to create a KnowledgeBuilder and then add the rules.
I’m creating the KnowledgeBase as follows.
private KnowledgeBase readKnowledgeBase() throws Exception {
long t1 = System.currentTimeMillis();
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
long t11 = System.currentTimeMillis();
kbuilder.add( org.drools.io.ResourceFactory.newByteArrayResource(getRule()), ResourceType.DRL);
long t2 = System.currentTimeMillis();
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
long t3 = System.currentTimeMillis();
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
long t4 = System.currentTimeMillis();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
long t5 = System.currentTimeMillis();
Collection<KnowledgePackage> kpackages = kbase.getKnowledgePackages();
for (KnowledgePackage knowledgePackage : kpackages) {
System.out.println("Package -------- " + knowledgePackage.getName());
Collection<Rule> rules = knowledgePackage.getRules();
for (Rule rule : rules) {
System.out.println("****" + rule.getName());
}
}
long t6 = System.currentTimeMillis();
System.out.println( (t11-t1) + " " + (t2-t11) + " " + ( t3-t2) + " " + ( t4-t3) + " " + ( t5-t4) + " " + ( t6-t5)+ " " );
return kbase;
}
Based on the timing logs the code take majority (more than 80%) of time in only these two operations. Is there a way to make it faster? OR is there a way of achieving my use case ?
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( org.drools.io.ResourceFactory.newByteArrayResource(getRule()), ResourceType.DRL);
The following call will actually compile your code, i.e., it calls the JDT java compiler:
kbuilder.add( org.drools.io.ResourceFactory.newByteArrayResource(getRule()), ResourceType.DRL);
There is no way of avoiding that unless you use internal APIs, that are in fact very complicated to use.
There is an intermediate step that is to generate the canonical model using the descriptor builder API. It will save you a few cycles, but not much as the heaviest operation is the java compilation. Examples of the use of the Descr Builder API:
https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/lang/api/DescrBuilderTest.java