I've had a look at execute(). It uses (indirectly) the API call Rete.eval()
for performing
the add-run-retract cycle. This loop, written in Jess and called from the
Jess prompt,
would be slow; but calling the Jess parser, repeatedly, is even slower.
Comparing
this to any other system would only be fair, if you'd tone down that other
system
likewise. Anyway, this style of coding isn't anywhere near what you'd do in
a production
system. I suggest that you rewrite the add-run-retract cycle to use the
corresponding
API calls.

Cheers
Wolfgang


On Wed, Feb 18, 2009 at 10: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].
> --------------------------------------------------------------------
>
>

Reply via email to