Hi Wolfgang,

    I guess this is why having a second pair of eyes (aka code review)
is a good thing! :P
Thank you very much for your prompt reply, and yes I can see that
executing the command parsing in a loop
would be errr... kinda slow :)  I'll take a look at the API and see if
I can pull together the corresponding commands
in java and see how that works.

Thanks again!
David

On Wed, Feb 18, 2009 at 4:43 PM, Wolfgang Laun <[email protected]> wrote:
> 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].
>> --------------------------------------------------------------------
>>
>
>


--------------------------------------------------------------------
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