XPath#evaluateを直接呼び出すのと、XPath#compileしておいたXPathExpression#evaluateではコンパイルしているぶんXPathExpression#evaluateの方が速いんだろうなぁ、とは考えていたがどの程度差があるのか気になって実験してみた。
利用したXMLはhttp://d.hatena.ne.jp/d-kami/rss2をローカルに保存してrss2というファイル名にしておき、XPathの"/rss/channel/title/text()"を1万回評価した時間を計測した
XPath#evaluateを直接呼び出したプログラム
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathExpression; import java.io.IOException; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; public class XPathTest { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); dbFactory.setNamespaceAware(true); DocumentBuilder builder = dbFactory.newDocumentBuilder(); Document document = builder.parse("rss2"); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); long start, end; start = System.currentTimeMillis(); for(int i = 0; i < 10000; i++){ xpath.evaluate("/rss/channel/title/text()", document); } end = System.currentTimeMillis(); double time = (double)(end - start) / 1000; System.out.println(time + "秒かかりました"); } }
XPath#compileしてからXPathExpression#evaluateを呼び出したプログラム
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathExpression; import java.io.IOException; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; public class XPathTest { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); dbFactory.setNamespaceAware(true); DocumentBuilder builder = dbFactory.newDocumentBuilder(); Document document = builder.parse("rss2"); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("/rss/channel/title/text()"); long start, end; start = System.currentTimeMillis(); for(int i = 0; i < 10000; i++){ expr.evaluate(document); } end = System.currentTimeMillis(); double time = (double)(end - start) / 1000; System.out.println(time + "秒かかりました"); } }
何度か繰り返して得た結果は
XPath#evaluateを直接呼び出したプログラム
6.7〜6.8秒XPath#compileしてからXPathExpression#evaluateを呼び出したプログラム
6.8〜6.9秒
と1万回繰り返して0.1秒以下の差とほとんど差が無かった。もっと差が出ると思ったけど特に差がでなかったのは意外だった。やり方次第で差がでるのだろうか?