性能かコーディング量か?RubyにおけるXMLライブラリーの選び方

REXMLとLibXML-Rubyのパフォーマンスを比較する

Rubyを使ってXMLデータを扱おうとした時、私たちは幾つかの選択肢からその方法を選ぶことができますが、実用面から考えた時にはパフォーマンス面での性能が利用可否に大きく影響します。本稿では特にREXMLとLibXml-Rubyの2つのライブラリーを取り上げ、XMLデータに対して処理を行った際のパフォーマンスについて確認します。その結果から、それぞれのライブラリーがどのようなシーンに向いているかについて考察します。

高橋 賢司, ICPアドバイザリーITアーキテクト, 日本アイ・ビー・エム株式会社

高橋賢司は日本IBM入社後、都銀のお客様へのシステム構築、データベース関連製品の提案時技術支援を経て、現在、ソフトウェアITアーキテクトとしてお客様のシステム・アーキテクチャー構築をソフトウェアの観点からお手伝いしています。DB2のpureXMLフィーチャー・リリース後、DB2におけるXMLの利用について検討を続けており、最近はRubyを用いてその検討を深めています。



2008年 9月 24日

Rubyを使ってXMLデータを扱おうとした時、私たちは幾つかの選択肢からその方法を選ぶことができます。それぞれのライブラリーには特徴がありますが、実用面から考えた時にはパフォーマンス面での性能が利用可否に大きく影響します。本稿では主要なライブラリーとして特にREXMLとLibXml-Rubyの2つに注目して、それらのパフォーマンスについて考察します。
一般的には、DOMを使うよりもストリーミング処理を行った方がパフォーマンスに優れると言われています。また、REXMLよりもLibXml-Rubyの方がパフォーマンスに優れるといわれ、簡単なベンチマークの結果がLibXml-Rubyのホームページにも紹介されています。
本稿では実際にXMLデータに対して処理を行い、パフォーマンス面でこの2つのライブラリーにどの程度の違いがあるかについて確認し、それぞれを利用する上でのスイートスポットを探したいと思います。処理を行うXMLデータには、現実的なデータとしてXBRLを利用します。

Ruby向けXMLライブラリー

RubyでXMLを扱う方法の一つはRubyの標準添付ライブラリーに含まれるREXMLを使う方法です。REXMLはRuby 1.8からのフィーチャーで、添付ライブラリー故にインストールなどを気にしなくていいというメリットが有ります。また、REXMLはpure Rubyで作られているという特徴があります。REXMLには、XMLデータを扱うために次のようなAPIが用意されています。

  • ツリー・ベースのAPI(DOM)
  • SAXライクなストリームAPI
  • SAX2ベースのAPI
  • プル・パーサーAPI

また、REXML以外に外部ライブラリーを利用することができます。そのようなライブラリーの一つにLibXml-Rubyがあります。LibXml-RubyはCで作られているGNOME LibXml2 XMLツールキットのRubyバインディングです。LibXml-Rubyには、XMLデータを扱うために次のようなAPIが用意されています。

  • ツリー・ベースのAPI(DOM)
  • Reader(プル・パーサー)API
  • SAX API

REXMLのインストール

REXMLはRuby 1.8以降で標準添付ライブラリーとして配布されています。RubyをインストールするだけでOKです。


LibXml-Rubyのインストール

LibXml-RubyはRubyGemsを利用してインストールすることができます。必要に応じてRubyGemsのupdateを行います。特にRuby One-Click Installerを利用している場合には、この作業が必要です。

リスト1. RubyGmesのアップデート
gem update –-system

それからLibXml-Rubyのインストールを行います。

リスト2. LibXml-Rubyのインストール
gem install libxml-ruby

パフォーマンス測定を行った処理

今回、REXMLとLibXml-Rubyでパフォーマンスを比較するに当たり、現実的なXMLデータとしてXBRLデータを用い、次のような処理を含むプログラムについて処理時間を測定しました。

  • 処理1:XBRLインスタンスのXMLデータを読み取り、{ノード名->値}のハッシュに読み取る
  • 処理2:XBRLインスタンスに対応するXMLスキーマと、各ノードのラベル名を定義するXMLファイルを読み取り、XBRLインスタンスの各ノード名とラベル名のマッチングを行い、{ノード名->ラベル名}のハッシュに読み取る

処理1は1つのXML文書のみを扱い、比較的簡単な処理のみを行うという特徴があります。
処理2は複数のXML文書を扱い、XML文書の中の複数のデータのマッチングを行うなど、処理1に比べ、より多くのXML文書を扱い、処理内容も複雑という特徴があります。
対象とするデータは東京証券取引所により提供されている決算短信のサンプル・データ、および、U.S. GAAPの2008年度のタクソノミーのサンプルとして提供されているデータを利用しました。

また、REXMLとLibXml-Rubyのそれぞれのライブラリーについて、XML文書をツリーとして扱うDOMと、ストリーム処理を行う方法とで処理時間を比較しました。ストリーム処理には大きく分けてプッシュ型とプル型の2種類があります。プッシュ型はパーサーがXML文書を解析していく中で開始タグの出現や終了タグの出現をそれぞれイベントとして扱い、リスナー・プログラム中でそれぞれのイベントに応じた処理を行うものです。プル型はXML文書の読み込みをプログラム内で制御し、それぞれのノードに応じた処理を行うものです。LibXml-Rubyでは、機能の豊富さとプログラミングのしやすさからプル型のLibXML::XML::Readerを用いました。一方で、REXMLではPullパーサーは現時点APIドキュメント上に“This API is experimental, and subject to change.”と記載されており、まだ開発途上であるため、プッシュ型のSAX2をストリーミング・パーサーとして利用しました。DOMとストリーム処理の特徴および長所、短所は表 1に示すとおりです。

表1. DOMとストリーミング・パーサーの特徴
DOMストリーム処理
特徴XMLデータをツリー構造でメモリーに展開して扱うXMLデータの各行を順に読み込み処理を行う
長所
  • XMLツリー内を自在に移動できる
  • XPathが利用できる
  • XML文書の作成が容易
  • 各行単独で処理が完結するような場合には、シンプルなプログラムを書くことができる
  • メモリー消費が比較的少ない
  • パフォーマンスに優れる
短所
  • メモリーを大量に消費する
  • パフォーマンスに劣る
  • XMLツリー内を自在に移動するような処理ができない
  • XML文書の作成には向かない

パフォーマンス測定結果

上述の処理1および処理2における、各パーサーが要した処理時間を表2、表3に示します。なお、これらの測定は著者のノートPC上で実施しています。テストした環境は次の通りです。

  • OS : Windows XP
  • CPU : Core2Duo T7300 2.0GHz
  • Memory : 2GB
  • Ruby : Ruby 1.8.6
  • LibXml-Ruby : 1.1.3
表2. 処理1の処理時間
XMLライブラリーREXMLlibXML
パーサーDOMSAX2DOMReader
処理時間(東証)[s]0.650.940.070.05
処理時間(U.S. GAAP)[s]0.691.060.070.06

まず処理1(表2) について見てみましょう。単独のXML文書を扱い、必要な要素のデータを単に上から順に読み出すような処理において、DOMとストリーミング・パーサーを比較した場合、REXML、LibXMLいずれの場合もそれほど大きな違いは出ていません。特にREXMLにおいてはDOMよりむしろSAX2の方が時間が掛かっています。これは、今回の測定した時間の中にリスナーの生成時間も含めたためと考えられます。また、REXMLとLibXMLを比較すると、LibXMLの方がDOMにおいておよそ1/10、ストリーミング・パーサーにおいておよそ1/20の処理時間で済んでいます。たいていの業務においてはREXMLにより提供されるパフォーマンスで十分かもしれませんが、それにしてもLibXMLの方が高速に処理を実行できることが読み取れます。

表3. 処理2の処理時間
XMLライブラリーREXMLlibXML
パーサーDOMSAX2DOMReader
処理時間(東証)[s]894.3535.7326.161.53
処理時間(U.S. GAAP)[s]4750.8973.0294.242.81

続いて、処理2(表3)を見てみましょう。処理1同様にDOMとストリーミング・パーサーで比較すると、いずれのXMLライブラリーでもストリーミング・パーサーの方が大幅に短時間で処理を行うことができています。これらの例では、DOMの方が17~65倍の時間が掛かる結果となっています。また、REXMLとLibXMLで比較すると、DOMでは30~50倍程度、ストリーミング・パーサーでは25倍程度REXMLの方が処理時間が掛かっています。このようにより多くのXML文書を一連の処理の中で扱う必要があり、ここのXML文書の中でもより複雑な処理を行うことにすると、顕著に処理時間の差が現れてきます。

表4. それぞれのパーサーのメモリー使用量
XMLライブラリーREXMLlibXML
パーサーDOMSAX2DOMReader
最大メモリー使用(東証) [MB]10993112
最大メモリー使用(U.S. GAAP)[MB]275177117

さらに、この時のメモリーの使用量を表4から確認してみましょう。ストリーミング・パーサーに比べてDOMの方が3~10倍と大幅に大きなメモリーを必要とすることが分かります。また、DOMを利用する場合でもLibXMLに比べてREXMLの方がより多くのメモリーを必要としています。


まとめ

以上のことから、REXMLとLibXMLそれぞれが向いているシチュエーションをまとめると次のようになります。

REXML:

  • 簡単にXMLデータを扱う処理を試してみたい時
  • 一度に扱うXMLデータの数が少ない時
  • XMLデータに対する処理が簡単な時

LibXML:

  • 少しでもパフォーマンスを良くしたい時
  • 一度に複数のXMLデータを扱う時
  • XMLデータに対して複雑な処理が必要な時

また、今回の一連の作業で同様の処理を行うプログラムについてREXMLとLibXml-Rubyの間、およびDOMとReaderまたはSAX2の間でポーティングを行っています。そこから、DOM同士であればREXMLからLibXmlへの移行は思ったより簡単にできることが分かりました。またDOMからReaderへの移行も、ちょっとの手間はありますがそれほど難しくありませんでした。SAX2については、イベント処理型のコーディングとなるため、それなりにプログラムを書き換える必要がありました。

参考文献

学ぶために

  • REXML (US): REXMLのホームページです。REXMLについての概要を知ることができます。TutorialおよびAPI Docへのリンクもあります。
  • XMLの論考:REXMLライブラリー」(David Mertz, Ph.D著、developerWorks、2002年3月): REXMLについて紹介されています。DOMおよびストリーム・モードそれぞれのコーディング例が示されており、どのようにコーディングするのかの理解を助けます。
  • 東証:決算短信XBRLデータ」: 今回テストデータとして用いたXBRLのサンプル・データを入手できます。
  • XBRL U.S.: 2008 U.S. GAAP Taxonomies 1.0 (US)」: 上に同じく、今回テストデータとして用いたXBRLのサンプル・データを入手できます。

製品や技術を入手するために

  • Rubyダウンロード」: Rubyを入手するためのさまざまな方法が説明されています。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, XML, Open source
ArticleID=430677
ArticleTitle=性能かコーディング量か?RubyにおけるXMLライブラリーの選び方
publish-date=09242008