Reusing parsed XPATH expressions

mark
2013-01-22
2013-05-15
  • mark
    mark
    2013-01-22

    I am using VTD for a pub/sub application where many simple XPATH expressions are evaluated against a lot of small XML docs.  The set of predicates are distinct, but they are reused for every xml doc that is published.

    The parse time is okay (10us/doc), the evalXPath is fast (3us).  It is the selectXPath that is killing me because it is about 70us and called many times per event.

    What I would like to do is to pre-parse the XPATH for each predicate and rapidly load the compiled XPATH into a new AutoPilot.  I tried to separate selectXPath into:
    Expr compileXPath(String s) and
    void selectXPath(Expr xpe)
    but no love.  Apparently the Expr is bound to the AutoPilot instance.  the question, I guess, is if there is any way to quickly rebind a compiled Xpath Expr to a different AutoPilot?

    thanks,
    Mark

     
  • mark
    mark
    2013-01-23

    Here is an example of what I wanted to do (this doesn't work).  The idea is that an XPath expression parsed on an earlier xml doc should be reusable on a new AutoPilot.  Currently, it isn't.

    public void selectXPath(String s) throws XPathParseException {
        try{
            CompiledXpath cXpath = xPathMap.get(s);
            if (cXpath != null ) {
                resetXPath();
                nsHash = cXpath.nsHash;
                symbolHash = cXpath.symbolHash;
                xpe = cXpath.compiledExpr;
            } else {
                   parser p = new parser(new StringReader(s));
                   p.nsHash = nsHash;
                   p.symbolHash = symbolHash;
                   xpe = (com.ximpleware.Expr) p.parse().value;
                   xPathMap.put(s,new CompiledXpath(s,nsHash,symbolHash,xpe));
            }
           ft = true;
           if (enableCaching)
               xpe.markCacheable();
        }catch(XPathParseException e){
            System.out.println("Syntax error after or around the end of ==>"+s.substring(0,e.getOffset()));
            throw e;
        }catch(Exception e){
            throw new XPathParseException("Error occurred");
        }
    }
    
     
  • jimmy zhang
    jimmy zhang
    2013-03-01

    sorry for the late reply, i think u may want to consider instantiating many instances of same xpath, that is to create more than one instance of AutoPilot before evaluating them wrt document….

     
    Last edit: jimmy zhang 2013-07-30
  • mark
    mark
    2013-05-02

    Wow! That made an incredible difference!  When evaluating 120 xpath expressions over 1000 small xml docs, the evaluation rate went from 28,680 evals/s to 697,000.  Almost 25x faster.  In the docs, I somehow got the impression that the AutoPilot was associated with the navigator, not the xpath expression.

    Thanks for your help.

        protected void evaluateSlow(List<String> expressions,String message) throws Exception{
            vg.setDoc(message.getBytes());
            vg.parse(false);
            VTDNav vn = vg.getNav();
            AutoPilot ap = new AutoPilot(vn);
            for(String expr : expressions) {
                boolean match;
                ap.selectXPath(expr);
                match = ap.evalXPathToBoolean();
                if ( match ) {
                    doSomethingUseful();
                }
            }
        }
        protected void evaluateFast(List<VtdXpathExpression> expressions,String message) throws Exception{
            vg.setDoc(message.getBytes());
            vg.parse(false);
            VTDNav vn = vg.getNav();
            for(VtdXpathExpression expr : expressions) {
                boolean match;
                AutoPilot ap = expr.getAutoPilot();
                ap.bind(vn);
                match = ap.evalXPathToBoolean();
                ap.resetXPath();
                if ( match ) {
                    doSomethingUseful();
                }
            }
        }