REXMLが遅い。遅すぎる件について
最初は気のせいかと思ったが。
<?xml version="1.0" encoding="Shift-JIS" standalone="yes"?> <items> <item> <url>http://newsing.jp/entry?url=headlines.yahoo.co.jp%2Fhl%3Fa%3D20070528-00000001-imp-sci</url> <title>東芝、「ぷよぷよ」もできる「gigabeat V」</title> <main_text></main_text> <picker>aplin</picker> <picktime>2007-05-29 01:04:32</picktime> <picker_eval>支持しない</picker_eval> <picker_com>gigabeatでぷよぷよをする意味など全くない。</picker_com> <pt>31</pt> <comments> <comment> <commenter>tera</commenter> <comtime>2007/05/29 02:45</comtime> <com_eval>○</com_eval> <com_text>Sの後継機出ないのかなぁ。</com_text> <nicecomment>0</nicecomment> </comment> <comment> <commenter>phantazy</commenter> <comtime>2007/05/29 10:32</comtime> <com_eval>○</com_eval> <com_text>ぷよぷよするな〜。</com_text> <nicecomment>0</nicecomment> </comment> </comments> </item> <item> (中略) </item> </items>
上記のようなitem要素が200個あるXMLをREXMLによってパースしてみた。
require 'kconv' require 'rexml/document' include REXML doc = REXML::Document.new File.open("newsing.xml","r") 1.upto(doc.root.elements.size) do |i| item = doc.root.elements["item[#{i}]"] puts item.text("url") puts item.text("title") puts item.text("main_text") puts item.text("picker") puts item.text("picktime") puts item.text("picker_eval") puts item.text("picker_com") puts item.text("pt") if item.text("comments") item.elements.each(".//comment") do |com| puts com.text("commenter") puts com.text("comtime") puts com.text("com_eval") puts com.text("com_text") puts com.text("nicecomment") end end end
俺の想定では5秒くらいでレスポンス返ってくると思っていたが、CPU100%のまま固まってまう。検証用にこんなコードを書いてみた。
require 'kconv' require 'rexml/document' include REXML require 'logger' log = Logger.new(STDOUT) log.level = Logger::INFO doc = REXML::Document.new File.open("V:/Prifiles/Prog/newsing/newsing.xml","r") log.info(Time.now) #=> I, [2007-06-01T22:20:32.640000 #4860] INFO -- : Fri Jun 01 22:20:32 +0900 2007 1.upto(100) do |i| item = doc.root.elements["item[#{i}]"] item.text("url") end log.info(Time.now) #=> I, [2007-06-01T22:20:44.728000 #4860] INFO -- : Fri Jun 01 22:20:44 +0900 2007 1.upto(100) do |i| doc.root.elements["item[#{i}]"].text("url") end log.info(Time.now) #=> I, [2007-06-01T22:20:56.434000 #4860] INFO -- : Fri Jun 01 22:20:56 +0900 2007
100個要素を探してくるのに12秒?ありえない。これは俺の間違いじゃないと確信し「google:REXML 遅い」で検索したら出るわ出るわ。
こりゃREXMLを諦めてlibxmlでやるか、そもそもXMLを使うのを諦めた方がいいのかなぁ…。
http://www.dt8.jp/cgi-bin/sb/sb.cgi?eid=278
http://hiroumitani.blog.drecom.jp/archive/96
結構メインのところまで実装したのでがっかり。