XPathの書き方でどのくらい速度に影響するのか

pythonlxmlを使ってXML文書内を検索するとき、XPathの書き方でどのくらい速度に影響するのか、簡単に試してみた。


まず、検索対象とするテストデータとして、Yahooからrssをダウンロードした。

$ wget -q http://blogs.yahoo.co.jp/rss.xml && mv rss.xml yahoo_list.rss
$ ls -hl | grep yahoo_list
-rw-rw-r-- 1 hogeuser hogeuser   11K  925 05:46 yahoo_list.rss
-rw-rw-r-- 1 hogeuser hogeuser 1011K  926 14:47 yahoo_list2.rss
※yahoo_list2.rssは、yahoo_list.rssを加工して100倍くらいにサイズを大きくした。


こんな感じのpythonスクリプトを実行してみる。

#!/usr/bin/env python
# -*- coding:utf8 -*-
import sys
import timeit
from lxml import etree

COUNT = 10000
XPATHS = [
    "//rss/channel/item/title", # 全要素が検索基準になる。
    "/rss/channel/item/title"   # ルートノードが検索基準になる。
]
print "SOURCE = %s" % sys.argv[1]
ET = etree.parse(sys.argv[1])

def find_by_xpath(xpath):
    global finded
    finded = ET.xpath(xpath)

for xpath in XPATHS:
    time_xp = timeit.Timer(
        setup='from __main__ import find_by_xpath',
        stmt=('find_by_xpath("%s")' % xpath)
    )
    print "  XPath = %s" % xpath
    print "  Time = %s" % time_xp.timeit(number=COUNT)
    print "  Items = %d\n" % len(finded)


以下、実行結果。

$ python -V
Python 2.4.3

$ python test_lxml_xpath.py yahoo_list.rss
SOURCE = yahoo_list.rss
  XPath = //rss/channel/item/title
  Time = 0.720010042191
  Items = 20

  XPath = /rss/channel/item/title
  Time = 0.690011024475
  Items = 20

$ python test_lxml_xpath.py yahoo_list2.rss
SOURCE = yahoo_list2.rss
  XPath = //rss/channel/item/title
  Time = 23.6503558159
  Items = 2000

  XPath = /rss/channel/item/title
  Time = 19.6602971554
  Items = 2000

”/rss/channel/item/title”の方が検索対象となるノードが少ない分だけ速くなったようだが、期待していたほど差が出なかった。

参考
XML/XPath/XPathの書き方 - 俺の基地