<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    On 16/07/2010 04:16, Jevon Wright wrote:
    <blockquote
      cite="mid:AANLkTikfKMqEauQSHcS8Twxmlgk_9f6XudDoMXy61u45@mail.gmail.com"
      type="cite">Hi again,<br>
      <br>
      By removing all of the simple eval()s from my rules, I have cut
      heap usage by at least an order of magnitude. However this still
      isn't enough.<br>
      <br>
      Since I am trying to reduce the cross-product size (as in SQL), I
      recall that most SQL implementations have a "DESCRIBE SELECT"
      query which provides real-time information about the complexity of
      a given SQL query - i.e. the size of the tables, indexes used, and
      so on. Is there any such tool available for Drools? Are there any
      tools which can provide clues as to which rules are using the most
      memory?<br>
    </blockquote>
    no, but sounds like a nice side project :)<br>
    <blockquote
      cite="mid:AANLkTikfKMqEauQSHcS8Twxmlgk_9f6XudDoMXy61u45@mail.gmail.com"
      type="cite">
      <br>
      Alternatively, I am wondering what kind of benefit I could expect
      from using materialized views to create summary tables; that is,
      deriving and inserting additional facts. This would allow Drools
      to rewrite queries that currently use eval(), but would increase
      the size of working memory, so would this actually save heap size?<br>
      <br>
      To what extent does Drools rewrite queries? Is there any
      documentation describing the approaches used?<br>
    </blockquote>
    The only rewriting we do is on literal constraints, moving == ones
    to the front, that's it. Also make sure you are using trunk, which
    is more memory efficient for modifies:<br>
<a class="moz-txt-link-freetext" href="https://hudson.jboss.org/hudson/job/drools/lastSuccessfulBuild/artifact/trunk/target/">https://hudson.jboss.org/hudson/job/drools/lastSuccessfulBuild/artifact/trunk/target/</a><br>
    <br>
    Mark<br>
    <blockquote
      cite="mid:AANLkTikfKMqEauQSHcS8Twxmlgk_9f6XudDoMXy61u45@mail.gmail.com"
      type="cite"><br>
      Any other ideas on how to reduce heap memory usage? I'd appreciate
      any ideas :)<br>
      <br>
      Thanks<br>
      Jevon<br>
      <br>
      <br>
      <div class="gmail_quote">On Mon, Jul 12, 2010 at 5:56 PM, Jevon
        Wright <span dir="ltr">&lt;<a moz-do-not-send="true"
            href="mailto:jevon@jevon.org">jevon@jevon.org</a>&gt;</span>
        wrote:<br>
        <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
          0.8ex; border-left: 1px solid rgb(204, 204, 204);
          padding-left: 1ex;">
          Hi Wolfgang and Mark,<br>
          <br>
          Thank you for your replies! You were correct: my eval()
          functions<br>
          could generally be rewritten into Drools directly.<br>
          <br>
          I had one function "connectsDetail" that was constraining<br>
          unidirectional edges, and could be rewritten from:<br>
          <div class="im"> &nbsp;detail : DetailWire ( )<br>
            &nbsp;eval ( functions.connectsDetail(detail, source, target) )<br>
            <br>
          </div>
          to:<br>
          &nbsp;detail : DetailWire ( from == source, to == target )<br>
          <br>
          Another function, "connects", was constraining bidirectional
          edges,<br>
          and could be rewritten from:<br>
          &nbsp;sync : SyncWire( )<br>
          &nbsp;eval ( functions.connects(sync, source, target) )<br>
          <br>
          to:<br>
          &nbsp;sync : SyncWire( (from == source &amp;&amp; to == target) ||
          (from == target<br>
          &amp;&amp; to == source) )<br>
          <br>
          Finally, the "veto" function could be rewritten from:<br>
          &nbsp;detail : DetailWire ( )<br>
          &nbsp;eval ( handler.veto(detail) )<br>
          <br>
          to:<br>
          &nbsp;detail : DetailWire ( overridden == false )<br>
          <br>
          I took each of these three changes, and evaluated them
          separately [1].<br>
          I found that:<br>
          <br>
          1. Inlining 'connectsDetail' made a huge difference - 10-30%
          faster<br>
          execution and 50-60% less allocated heap.<br>
          2. Inlining 'connects' made very little difference - 10-30%
          faster<br>
          execution, but 0-20% more allocated heap.<br>
          3. Inlining 'veto' made no difference - no significant change
          in<br>
          execution speed or allocated heap.<br>
          <br>
          I think I understand why inlining 'connects' would improve
          heap usage<br>
          - because the rules essentially have more conditionals?<br>
          <br>
          I also understand why 'veto' made no difference - for most of
          my test<br>
          models, "overridden" was never true, so adding this
          conditional was<br>
          not making the cross product set any smaller.<br>
          <br>
          Finally, I also tested simply joining all of the rules
          together into<br>
          one file. This happily made no difference at all (although
          made it<br>
          more difficult to edit).<br>
          <br>
          So I think I can safely conclude that eval() should be used as
          little<br>
          as possible - however, this means that the final rules are
          made more<br>
          complicated and less human-readable, so a DSL may be best for
          my<br>
          common rule patterns in the future.<br>
          <br>
          Thanks again!<br>
          Jevon<br>
          <br>
          [1]: <a moz-do-not-send="true"
            href="http://www.jevon.org/wiki/Improving_Drools_Memory_Performance"
            target="_blank">http://www.jevon.org/wiki/Improving_Drools_Memory_Performance</a><br>
          <div>
            <div class="h5"><br>
              On Sat, Jul 10, 2010 at 12:28 AM, Wolfgang Laun &lt;<a
                moz-do-not-send="true"
                href="mailto:wolfgang.laun@gmail.com">wolfgang.laun@gmail.com</a>&gt;
              wrote:<br>
              &gt; On 9 July 2010 14:14, Mark Proctor &lt;<a
                moz-do-not-send="true"
                href="mailto:mproctor@codehaus.org">mproctor@codehaus.org</a>&gt;
              wrote:<br>
              &gt;&gt; &nbsp;You have many objects there that are not
              constrained;<br>
              &gt;<br>
              &gt; I have an inkling that the functions.*() are hiding
              just these contraints,<br>
              &gt; It's certainly the wrong way, starting with oodles of
              node pairs, just to<br>
              &gt; pick out connected ones by fishing for the connecting
              edge. And this<br>
              &gt; is worsened by trying to find two such pairs which
              meet at some<br>
              &gt; DomainSource<br>
              &gt;<br>
              &gt; Guesswork, hopefully educated ;-)<br>
              &gt;<br>
              &gt; -W<br>
              &gt;<br>
              &gt;<br>
              &gt;&gt; if there are<br>
              &gt;&gt; multiple versions of those objects you are going
              to get massive amounts<br>
              &gt;&gt; of cross products. Think in terms of SQL, each
              pattern you add is like<br>
              &gt;&gt; an SQL join.<br>
              &gt;&gt;<br>
              &gt;&gt; Mark<br>
              &gt;&gt; On 09/07/2010 09:20, Jevon Wright wrote:<br>
              &gt;&gt;&gt; Hi everyone,<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; I am working on what appears to be a fairly
              complex rule base based on<br>
              &gt;&gt;&gt; EMF. The rules aren't operating over a huge
              number of facts (less than<br>
              &gt;&gt;&gt; 10,000 EObjects) and there aren't too many
              rules (less than 300), but<br>
              &gt;&gt;&gt; I am having a problem with running out of
              Java heap space (set at ~400<br>
              &gt;&gt;&gt; MB).<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Through investigation, I came to the
              conclusion that this is due to<br>
              &gt;&gt;&gt; the design of the rules, rather than the
              number of facts. The engine<br>
              &gt;&gt;&gt; uses less memory inserting many facts that
              use simple rules, compared<br>
              &gt;&gt;&gt; with inserting few facts that use many rules.<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Can anybody suggest some tips for reducing
              heap memory usage in<br>
              &gt;&gt;&gt; Drools? I don't have a time constraint, only
              a heap/memory constraint.<br>
              &gt;&gt;&gt; A sample rule in my project looks like this:<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; &nbsp; &nbsp;rule "Create QueryParameter for target
              container of DetailWire"<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp;when<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;container : Frame( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;schema : DomainSchema ( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;domainSource : DomainSource ( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;instance : DomainIterator( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;selectEdge : SelectEdge ( eval (<br>
              &gt;&gt;&gt; functions.connectsSelect(selectEdge,
              instance, domainSource )) )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;schemaEdge : SchemaEdge ( eval (<br>
              &gt;&gt;&gt; functions.connectsSchema(schemaEdge,
              domainSource, schema )) )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;source : VisibleThing ( eContainer ==
              container )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;target : Frame ( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;instanceSet : SetWire (
              eval(functions.connectsSet(instanceSet,<br>
              &gt;&gt;&gt; instance, source )) )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;detail : DetailWire ( )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;eval (
              functions.connectsDetail(detail, source, target ))<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;pk : DomainAttribute ( eContainer ==
              schema, primaryKey == true )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;not ( queryPk : QueryParameter (
              eContainer == target, name == <a moz-do-not-send="true"
                href="http://pk.name" target="_blank">pk.name</a> ) )<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;eval ( handler.veto( detail ))<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp;then<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;QueryParameter qp =
              handler.generatedQueryParameter(detail, target);<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;handler.setName(qp, pk.getName());<br>
              &gt;&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;queue.add(qp, drools); // wraps
              insert(...)<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; &nbsp; &nbsp;end<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; I try to order the select statements in an
              order that will reduce the<br>
              &gt;&gt;&gt; size of the cross-product (in theory), but I
              also try and keep the<br>
              &gt;&gt;&gt; rules fairly human readable. I try to avoid
              comparison operators like<br>
              &gt;&gt;&gt; &lt; &nbsp;and&gt;. Analysing a heap dump shows
              that most of the memory is being<br>
              &gt;&gt;&gt; used in StatefulSession.nodeMemories&gt;
              &nbsp;PrimitiveLongMap.<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; I am using a StatefulSession; if I understand
              correctly, I can't use a<br>
              &gt;&gt;&gt; StatelessSession with sequential mode since I
              am inserting facts as<br>
              &gt;&gt;&gt; part of the rules. If I also understand
              correctly, I'd like the Rete<br>
              &gt;&gt;&gt; graph to be tall, rather than wide.<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Some ideas I have thought of include the
              following:<br>
              &gt;&gt;&gt; 1. Creating a separate intermediary
              meta-model to split up the sizes<br>
              &gt;&gt;&gt; of the rules. e.g. instead of (if A and B and
              C then insert D), using<br>
              &gt;&gt;&gt; (if A and B then insert E; if E and C then
              insert D).<br>
              &gt;&gt;&gt; 2. Moving eval() statements directly into the
              Type(...) selectors.<br>
              &gt;&gt;&gt; 3. Removing eval() statements. Would this
              allow for better indexing by<br>
              &gt;&gt;&gt; the Rete algorithm?<br>
              &gt;&gt;&gt; 4. Reducing the height, or the width, of the
              class hierarchy of the<br>
              &gt;&gt;&gt; facts. e.g. Removing interfaces or abstract
              classes to reduce the<br>
              &gt;&gt;&gt; possible matches. Would this make a
              difference?<br>
              &gt;&gt;&gt; 5. Conversely, increasing the height, or the
              width, of the class<br>
              &gt;&gt;&gt; hierarchy. e.g. Adding interfaces or abstract
              classes to reduce field<br>
              &gt;&gt;&gt; accessors.<br>
              &gt;&gt;&gt; 6. Instead of using EObject.eContainer,
              creating an explicit<br>
              &gt;&gt;&gt; containment property in all of my EObjects.<br>
              &gt;&gt;&gt; 7. Creating a DSL that is human-readable, but
              allows for the<br>
              &gt;&gt;&gt; automation of some of these approaches.<br>
              &gt;&gt;&gt; 8. Moving all rules into one rule file, or
              splitting up rules into<br>
              &gt;&gt;&gt; smaller files.<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Is there kind of profiler for Drools that
              will let me see the size (or<br>
              &gt;&gt;&gt; the memory usage) of particular rules, or of
              the memory used after<br>
              &gt;&gt;&gt; inference? Ideally I'd use this to profile
              any changes.<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Thanks for any thoughts or tips! :-)<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt; Jevon<br>
              &gt;&gt;&gt;
              _______________________________________________<br>
              &gt;&gt;&gt; rules-users mailing list<br>
              &gt;&gt;&gt; <a moz-do-not-send="true"
                href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
              &gt;&gt;&gt; <a moz-do-not-send="true"
                href="https://lists.jboss.org/mailman/listinfo/rules-users"
                target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
              &gt;&gt;&gt;<br>
              &gt;&gt;&gt;<br>
              &gt;&gt;<br>
              &gt;&gt;<br>
              &gt;&gt; _______________________________________________<br>
              &gt;&gt; rules-users mailing list<br>
              &gt;&gt; <a moz-do-not-send="true"
                href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
              &gt;&gt; <a moz-do-not-send="true"
                href="https://lists.jboss.org/mailman/listinfo/rules-users"
                target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
              &gt;&gt;<br>
              &gt;<br>
              &gt; _______________________________________________<br>
              &gt; rules-users mailing list<br>
              &gt; <a moz-do-not-send="true"
                href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
              &gt; <a moz-do-not-send="true"
                href="https://lists.jboss.org/mailman/listinfo/rules-users"
                target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
              &gt;<br>
            </div>
          </div>
        </blockquote>
      </div>
      <br>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
rules-users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>