Hi Peter,

   Thank you for getting back to me. You bring up some interesting
points, thanks again!

David

On Wed, Feb 18, 2009 at 5:18 PM, Peter Lin <[email protected]> wrote:
> A couple of important things to consider.
>
> By default drools uses compiled mode, which means it compiles code to
> pure java when the ruleset is loaded.
>
> To be fair, you'd have to run Drools in interpreted mode and force
> drools to use mvel to evaluate the mod test.
>
> the other option is to write a java function that implements JESS
> function interface and don't use TESTCE. Instead do something like
>
> (Random
>  (x ?x&:(isPrime ?x))
> )
>
> the isPrime would be a function that returns true/false
>
> Another important thing to consider is that JESS is an expert system
> shell, whereas drools is a business rule engine. The two are similar,
> but not comparable on many levels. For example, JESS does type
> coercion and provide a declarative + functional approach. JESS also
> has solid support for multi-threaded environments, whereas drools does
> not in version 4.x.
>
> the other important thing to consider is you have to increase the
> PermGen heap setting to get drools to load more than 15K rules in
> compiled mode with Sun or IBM JDK. If you need to load 30K rules,
> drools is going to hit the Perm limit very quickly, whereas JESS will
> not.
>
> peter
>
> On Wed, Feb 18, 2009 at 4:28 PM, David Ray <[email protected]> wrote:
>> Hi,
>>  I am conducting a test of Jess where I am inserting 10,000 rules -
>> each matching a particular modulus of a prime number and then calling
>> code to aggregate prime roots of those numbers being matched. The test
>> submits 100 random numbers one by one - each matching against one of
>> the 10,000 rules - and the result is timed. It is a test I grabbed
>> from one of the tests in the drools package which basically stress
>> tests the rule engine and outputs timing results. I am doing this to
>> compare the total computation time between Drools and Jess - and Jess
>> is about 6 times slower, but I think the problem may not be Jess
>> itself but either how my rules are constructed or some problem where
>> Jess isn't flushing the I/O stream properly.
>>
>> Of particular note are the prepareConstructs() method where the rules
>> are being built, and the execute() method where the rule engine is
>> iteratively being invoked.
>>
>> I am attaching an executable Jar file which can be run via the
>> command: java -jar primeNumTest.jar  -or- java -cp primeNumTest.jar
>> PrimeFactorsTest
>>
>> Also, I am attaching the two java source files to this message.
>> Program flow is pretty easy to follow looking at the "main" method in
>> PrimeFactorsTest.java.
>>
>> I am very interested in using Jess and am evaluating its usage for my
>> company, but this initial test presents some problems...
>>
>> Can anyone take a look at this and maybe tell me or point to what the
>> problem may be?
>>
>> I'm a first-time majordomo user, and I seem to have a problem with
>> posting (I guess
>> you can't use attachments?) So I'm posting the 2 java source files inline 
>> below,
>> which can be compiled and run against jess.jar
>>
>> Thanks ahead of time,
>> David
>>
>> ====================
>>
>>
>>
>> import java.io.BufferedReader;
>> import java.io.InputStreamReader;
>> import java.util.Random;
>>
>> import jess.JessException;
>> import jess.Rete;
>> import jess.Value;
>>
>>
>> /**
>>  * By default, creates 10,000 rules each matching a single prime number -
>>  * then inserts 100 random integers into the engine and collects those
>>  * rules which have fired, and all their roots outputting the timing
>>  * for each stage and each calculation.
>>  *
>>  * See the main() method (at the bottom) for program flow.
>>  *
>>  * @author David Ray
>>  */
>> public class PrimeFactorsTest
>> {
>>   private long seed;
>>   private long start;
>>   private long total;
>>   private int numRules;
>>   private int[] primes;
>>   private int[] randomNumbers;
>>   private Rete rete;
>>   private static long[] timepoint = new long[2];
>>
>>       PrimeFactorsTest(int seed)
>>       {
>>               this.seed = seed;
>>               this.rete = new Rete();
>>       }
>>
>>       /**
>>        * Generates "numFacts" number of random numbers.
>>        *
>>        * @param numFacts
>>        */
>>       public void createRandomNums(int numFacts)
>>       {
>>               System.out.println("Generating random number knowledge...");
>>           Random rand = new Random(seed);
>>           randomNumbers = new int[numFacts];
>>           start = System.currentTimeMillis();
>>           for(int i = 0;i < numFacts;i++) {
>>             int nextRand = rand.nextInt(primes[numRules - 1])  + 1;
>>             if(nextRand < 1) {--i; continue;}
>>             randomNumbers[i] = nextRand;
>>           }
>>           total = (System.currentTimeMillis() - start);
>>           System.out.println("Generated "+numFacts+" random numbers in
>> ["+total+" msecs.]");
>>       }
>>
>>       /**
>>        * Inserts a "Jess" formatted command into the Jess Rete engine.
>>        *
>>        * @param statement
>>        * @return      Value   A jess.Value object representing the
>> result obtained
>>        *                                      from executing the
>> specified statement.
>>        */
>>       public Value insertStatement(String statement)
>>       {
>>               Value retVal = null;
>>               try {
>>                       retVal  = rete.eval(statement);
>>           }catch(JessException e) {
>>               e.printStackTrace();
>>           }
>>           return retVal;
>>       }
>>
>>       /**
>>        * Inserts 10,000 rules into the working memory - each representing
>>        * a "pattern" which will only activate if the LHS is true (meaning
>>        * that the unique prime number correlated with each rule is a prime
>>        * root of the asserted random number).
>>        */
>>       public void prepareConstructs()
>>       {
>>               /////////////////////////////////////////////
>>               //Used for debugging
>>               //String statement = "(watch all)";
>>               //insertStatement(statement);
>>
>>               System.out.println("-----------------------");
>>
>>               System.out.println("Creating New RuleBase...");
>>           start = System.currentTimeMillis();
>>
>>               String statement = "(deftemplate RandomNumber (declare
>> (from-class
>> RandomNumber)))";
>>               insertStatement(statement);
>>
>>               for(int divisor : primes)
>>               {
>>                       statement = "(defrule modulus"+divisor+
>>                               " (RandomNumber (value ?x))" +
>>                               " (test (eq 0 (mod ?x "+divisor+")))"+
>>                               "=>"+
>>                               "(call ?a extractRoots "+divisor+"))";
>>
>>                       insertStatement(statement);
>>               }
>>
>>               total = (System.currentTimeMillis() - start) / 1000;
>>           System.out.println("Created new RuleBase with "+numRules+" rules
>> in ["+total+" secs.]");
>>       }
>>
>>       /**
>>        * Binds a new RandomNumber object containing a unique random
>>        * number. Then adds the random number fact causing the matching
>>        * rules to activate. Following this, "run" is called to actually
>>        * fire the rules. The "bound" RandomNumber (and the contained
>>        * prime roots) are then printed out and "retract" is called to
>>        * "clear" the working memory of the last fact and the process
>>        * then continues until all RandomNumbers have been processed.
>>        */
>>       public void execute()
>>       {
>>               System.out.println("-----------------------");
>>               System.out.println("Starting test...");
>>           total = 0;
>>
>>           stopwatch(0);
>>
>>           for(int randNum : randomNumbers)
>>               {
>>               stopwatch( 1 );
>>
>>                       String statement = "(bind ?a (new RandomNumber
>> "+randNum+"))";
>>                       insertStatement(statement);
>>
>>                       //Add a Fact causing Activation to happen here.
>>                       statement = "(add ?a)";
>>                       insertStatement(statement);
>>
>>                       //Rule Fire happens here.
>>                       statement = "(run)";
>>                       insertStatement(statement);
>>
>>                       statement = "(printout t (call ?a toString) :
>> "+stopwatch( 1 )+" crlf)";
>>                       insertStatement(statement);
>>
>>                       statement = "(retract 1)";
>>                       insertStatement(statement);
>>               }
>>
>>           System.out.println("Total Engine Time: " + stopwatch(0));
>>       }
>>
>>       /**
>>        * Reads a file containing "numRules" number of prime numbers into
>>        * an array which is later used to generate a unique rule for each
>>        * prime number.
>>        *
>>        * @param numRules
>>        */
>>       public void loadPrimeList(int numRules)
>>       {
>>           this.numRules = numRules;
>>           BufferedReader buf = null;
>>           try {
>>                 buf = new BufferedReader(
>>                   new InputStreamReader(
>>
>> getClass().getClassLoader().getResourceAsStream("1100000-primes.txt")));
>>                 String line = null;
>>                 int count = 0;
>>                 System.out.println("Reading "+numRules+" Prime Numbers");
>>                 start = System.currentTimeMillis();
>>                 primes = new int[numRules];
>>                 while((line = buf.readLine()) != null && ((count) <
>> numRules)) {
>>                   primes[count++] = Integer.parseInt(line.trim());
>>                 }
>>                 total = (System.currentTimeMillis() - start);
>>                 System.out.println("Read "+primes.length+" Prime Numbers
>> ["+total+" msecs.]");
>>           }
>>           catch(Exception e) { e.printStackTrace(); }
>>           finally {
>>             try { buf.close(); }catch(Exception ignore) {}
>>           }
>>       }
>>
>>       /**
>>        * Returns and records time points specified by the index "i"
>>        * passed in.
>>        *
>>        * @param i
>>        * @return message      A formatted String containing the
>> specified time point.
>>        */
>>       private static String stopwatch(int i)
>>       {
>>       long now = System.currentTimeMillis( );
>>           String message = " [" + ( now - timepoint[i] )  + " msecs]";
>>           timepoint[i] = now;
>>           return message;
>>       }
>>
>>       public static void main(String[] args)
>>       {
>>               int seed = 0;
>>               int numRules = 10000;
>>               int numFacts = 100;
>>
>>               if(args != null && args.length == 3) {
>>                       seed = Integer.parseInt(args[2]);
>>                       numRules = Integer.parseInt(args[0]);
>>                       numFacts = Integer.parseInt(args[1]);
>>               }
>>
>>               PrimeFactorsTest pft = new PrimeFactorsTest(seed);
>>           System.out.println("Number of Rules: "+numRules);
>>           System.out.println("Number of Facts: "+numFacts);
>>           System.out.println("Random Seed: "+seed);
>>
>>           pft.loadPrimeList(numRules);
>>           pft.createRandomNums(numFacts);
>>
>>               pft.prepareConstructs();
>>               pft.execute();
>>       }
>> }
>>
>> ===================
>>
>>
>>
>> import java.util.ArrayList;
>> import java.util.List;
>>
>> /**
>>  * Stores a random integer value and can extract and store multiples of
>>  * a specified prime root correlated to the original initialized value.
>>  *
>>  * @author davidray
>>  */
>> public class RandomNumber {
>>
>>       Integer value;
>>       int quotient = 1;
>>       List<Integer> primeList = new ArrayList<Integer>();
>>
>>       public RandomNumber() {}
>>
>>       public RandomNumber(Integer number)
>>       {
>>               this.value = number;
>>               this.quotient = number.intValue();
>>       }
>>
>>       /**
>>        * Operates on this <code>RandomNumber</code>'s value using the
>>        * specified prime root by extracting the greatest number of the
>>        * specified prime root, saving each root in a list of roots.
>>        *
>>        * @param primeRoot
>>        */
>>       public void extractRoots(Integer primeRoot)
>>       {
>>               quotient = value.intValue();
>>               int pFactor = primeRoot.intValue();
>>               do {
>>                       primeList.add(primeRoot);
>>                       quotient = quotient / pFactor;
>>               } while(quotient % pFactor == 0);
>>       }
>>
>>       /**
>>        * Returns the original value with which this
>> <code>RandomNumber</code> was
>>        * initialized.
>>        *
>>        * @return Integer      the original value.
>>        */
>>       public Integer getValue()
>>       {
>>               return value;
>>       }
>>
>>       @Override
>>       public int hashCode() {
>>               final int prime = 31;
>>               int result = 1;
>>               result = prime * result + ((value == null) ? 0 :
>> value.hashCode());
>>               return result;
>>       }
>>
>>       @Override
>>       public boolean equals(Object obj) {
>>               if (this == obj)
>>                       return true;
>>               if (obj == null)
>>                       return false;
>>               if (getClass() != obj.getClass())
>>                       return false;
>>               RandomNumber other = (RandomNumber) obj;
>>               if (value == null) {
>>                       if (other.value != null)
>>                               return false;
>>               } else if (!value.equals(other.value))
>>                       return false;
>>               return true;
>>       }
>>
>>       @Override
>>       public String toString()
>>       {
>>               return "Number ("+value+")  Prime Numbers: "+primeList;
>>       }
>> }
>>
>> =======================
>>
>>
>> --------------------------------------------------------------------
>> To unsubscribe, send the words 'unsubscribe jess-users [email protected]'
>> in the BODY of a message to [email protected], NOT to the list
>> (use your own address!) List problems? Notify [email protected].
>> --------------------------------------------------------------------
>>
>>
>
>
> --------------------------------------------------------------------
> To unsubscribe, send the words 'unsubscribe jess-users [email protected]'
> in the BODY of a message to [email protected], NOT to the list
> (use your own address!) List problems? Notify [email protected].
> --------------------------------------------------------------------
>
>


--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [email protected]'
in the BODY of a message to [email protected], NOT to the list
(use your own address!) List problems? Notify [email protected].
--------------------------------------------------------------------

Reply via email to