ページ更新: 2006-09-29 (金) (4494日前)

(2006-09-29 新規作成)

JAXPに関するメモ。

[編集]

developerWorks: Java XPath API Java プログラムから XML をクエリーする (2006-09-29) #

developerWorks: Java XPath API Java プログラムから XML をクエリーする 2006年7月25日
http://www-06.ibm.com/jp/developerworks/java/060906/j_x-javaxpathapi.shtml

を見て、ちょいとベンチマークを取ってみた。

JDK 1.5.8_08、ClientVMを使用。また、JDK 1.6.0 (Java 6 beta2) も試したが、傾向は変わらず。

プログラム // //

// http://www-06.ibm.com/jp/developerworks/java/060906/j_x-javaxpathapi.shtml

package sample;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XPathTrial {
    private static class StopWatch {
        private long startNanoTime;
        private long lapsedNanoTime;
        public void start() { startNanoTime = System.nanoTime(); }
        public void stop() { lapsedNanoTime = System.nanoTime() - startNanoTime; }
        public void reset() { startNanoTime = 0; lapsedNanoTime = 0; }
        public double timeMillis() { return lapsedNanoTime / (1000.0 * 1000.0); }
    }

    private static final int WARMUP_LOOPS = 1000;
    private static final int BENCH_LOOPS = 1;

    public static void main(final String[] args) throws SAXException, IOException,
            ParserConfigurationException, XPathExpressionException {

        final DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true); // never forget this!
        final DocumentBuilder builder = domFactory.newDocumentBuilder();
        final Document doc = builder.parse("books.xml");

        final StopWatch watch = new StopWatch();

        // warmup
        System.out.println("warmup...");
        for (int w = 0; w < 10; w++) {
            for (int i = 0; i < WARMUP_LOOPS; i++) {
                domSearch(doc, false);
            }
            for (int i = 0; i < WARMUP_LOOPS; i++) {
                xPathSearch(doc, false);
            }
        }

        // bench

        System.out.println("-------------------------------- DOM search");
        domSearch(doc, true);
        watch.start();
        for (int i = 0; i < BENCH_LOOPS; i++) {
            domSearch(doc, false);
        }
        watch.stop();
        System.out.println("time=" + watch.timeMillis() / (double) BENCH_LOOPS + " ms.");

        System.out.println("-------------------------------- XPath search");
        xPathSearch(doc, true);
        watch.start();
        for (int i = 0; i < BENCH_LOOPS; i++) {
            xPathSearch(doc, false);
        }
        watch.stop();
        System.out.println("time=" + watch.timeMillis() / (double) BENCH_LOOPS + " ms.");
    }

    private static void xPathSearch(final Document doc, final boolean sysout) throws XPathExpressionException {
        final XPathFactory factory = XPathFactory.newInstance();
        final XPath xpath = factory.newXPath();
//        final XPathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()");
        final XPathExpression expr = xpath.compile("/inventory/book[author='Neal Stephenson']/title/text()");

        final Object result = expr.evaluate(doc, XPathConstants.NODESET);
        final NodeList nodes = (NodeList) result;
        for (int i = 0; i < nodes.getLength(); i++) {
            if (sysout) {
                System.out.println(nodes.item(i).getNodeValue());
            }
        }
    }

    private static void domSearch(final Document doc, final boolean sysout) {
        final NodeList books = doc.getElementsByTagName("book");
        for (int i = 0; i < books.getLength(); i++) {
            final Element book = (Element) books.item(i);
            final NodeList authors = book.getElementsByTagName("author");
            boolean stephenson = false;
            for (int j = 0; j < authors.getLength(); j++) {
                final Element author = (Element) authors.item(j);
                final NodeList children = author.getChildNodes();
                final StringBuffer sb = new StringBuffer();
                for (int k = 0; k < children.getLength(); k++) {
                    final Node child = children.item(k);
                    // really should to do this recursively
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        sb.append(child.getNodeValue());
                    }
                }
                if (sb.toString().equals("Neal Stephenson")) {
                    stephenson = true;
                    break;
                }
            }

            if (stephenson) {
                final NodeList titles = book.getElementsByTagName("title");
                for (int j = 0; j < titles.getLength(); j++) {
                    final Node node = titles.item(j);
                    if (sysout) {
                        System.out.println(node.getChildNodes().item(0).getNodeValue());
                    }
                }
            }
        }
    }
}

結果

warmup...
-------------------------------- DOM search
Snow Crash
Zodiac
time=0.099055 ms.
-------------------------------- XPath search
Snow Crash
Zodiac
time=1.024646 ms.