レベル: 中級 Dennis Sosnoski (dms@sosnoski.com), President, Sosnoski Software Solutions, Inc.
2004年 06月 15日 XML文書はテキスト・ベースであるため多くの利点がありますが、転送のパフォーマンスにおいてはあまり利点がありません。XML文書の代替表現を使用すると、テキストよりもずっと小さく、高速に処理できるようになります。2回構成のこの記事の第1回では、XML文書の代替表現の基礎を説明しました。この第2回では、Dennis Sosnoskiが様々なXML文書をそれぞれ、テキストで、gzipで、そしてXBISで表現した場合の実際のサイズと処理のオーバーヘッドについて比較を行います。また最後に、XMLの非テキスト表現の標準化に向けて次第に活発になりつつある動向について紹介します。
このシリーズの第1回では、XMLをテキスト表現した場合と代替表現を使用した場合との比較に関わる問題の背景を説明しました。今回は第2回目として、様々な表現を使う上で関係してくる、実際のパフォーマンス上の兼ね合いについて説明して行きます。ただし包括的な比較を意図しているわけではありません(スキーマから生成された、それぞれの文書型式に固有のバイナリ表現を含めて、代替表現の方法にはあまりにも多くの選択肢があるからです)。ところが、代替表現に関する議論はえてして感情論が延々と続き、本当の事実に関する議論はごく僅か、となりがちでした。ここではパフォーマンスの測定結果を踏まえ、このような比較に関心を持つ開発者に対して、少なくとも何らかの足がかりを与えたいと思っています。
測定しましょう
様々な表現方法による文書サイズの比較は簡単です。単に同じデータを各形式で書き出し、各々の場合におけるバイト数を記録します。処理速度の比較にはちょっと細工が要ります。私は公正な比較をするために、各表現をアプリケーションが使う形式に変換する上でのオーバーヘッドや、アプリケーションの内部データからその表現を生成する上でのオーバーヘッドを調べる必要がありました。ところが、どのアプリケーションもそれぞれ独自の内部データを持っているものです。では様々なアプリケーションのどれに対しても公正な選択というのは、一体どんなものになるのでしょうか・・・?
これに対する私の答えは、XML文書に対して構文解析イベント・ストリーム表現を使うというものです。XMLを使用するアプリケーションはほとんど全て、入力で文書をパーサに通し、そして多くは構文解析イベントに対応するストリームを出力文書に対して生成するので、この選択は公正なものと言えそうです。私はこのテストの基準に、Java言語用のパーサとして現在最も広く使用されているSAX2パーサ・モデルを選択しました。
テストの詳細
私は可能な限り標準のJavaコンポーネントを使い、全てのテスト・コードをJavaで書きました。このテスト・コード(参考文献にリンクがある、XBISのサイトからダウンロードすることができます)は、最初に各テスト文書を構文解析し、構文解析で生成されたイベントのストリームをメモリに保存します。これによって、構文解析のイベント・ストリームをほとんどオーバーヘッド無く、後で再生することができます。そして、保存した構文解析イベント・ストリームを使って下記を生成します。
- テキストXML:
javax.xml.transform.Transformerのtransformメソッドの入力とすることでコピーを生成します(私が思いついた手法のうちで、最も速い方法です)。
- テキストをgzipする: 生成されるテキストを
java.util.zip.GZIPOutputStream に関連付けることによって生成します。
- あるいはXBISにする:
org.xbis.SAXToXBISAdapterへの入力として与えることで生成します。
各表現のサイズを記録し、それから今度は(向きを変えて)生成された出力を入力として処理し、それぞれの場合(単にテキスト形式を構文解析する場合、gzipされたテキストに対してjava.util.zip.GZIPInputStreamをパーサに関連付ける場合、またはXBISをorg.xbis.XBISToSAXAdapterデコーダへの入力として与える場合)の入力処理のオーバーヘッドを測定します。それぞれの場合において、生成された出力を処理するとSAX2構文解析イベント・ストリームが生成されるので、元々の文書内容が成功裏に往復したことを確認するために構文解析イベントを集約します。
この記事にある実際の測定時間の値は、それぞれの表現を使った同じ文書または同じ文書集合に対して、10パス(読込みと書出しをそれぞれ5回)実行し、最も成績の良かった時間だけをとった結果から得られたものです。別々に時間を測定できるように、各パスに対して完全な往復は実行せず、出力生成パスを最初に実行してから次に入力処理パスを実行しました。また、一連のテストから、別の一連のテストに対してJVMの最適化が持ち越されてしまうような副作用を避けるために、それぞれの表現方法に対してテストを別々に実行しました。この時間測定には、Mandrake Linux 9.1 上で IBM 1.4.1 JVM for Linux を実行している Athlon 2000+ システムを使っています。Sun 1.4.2 JVM を使用したテストでは、gzipテストを実行したパフォーマンスがここに示す結果よりも大幅に悪く、出力処理に約7倍長くかかっています。ただしgzipのテスト時間を別にすれば、2つのJVMでは似たようなテスト結果が得られます。ここで示す測定時間の結果には、Piccolo SAX2パーサを使用していますが、これは確認したSAX2パーサの中で最速のパフォーマンスが得られたためです。
テスト文書
テスト・データとしては、小さな文書を幾つか集めたものと、中規模、大規模な個別文書に分類しました。中規模の文書は、次のようなものです。
-
periodic.xml: XMLで表現した、元素周期表(114Kバイト)
-
soap.xml: テスト用Webサービスから取得した、SOAPのレスポンス・メッセージ(157Kバイト)
-
xml.xml: 実体をインラインで定義した、XML勧告の文書(156Kバイト)
大規模な文書は、次のようなものです。
-
weblog.xml: XMLとして再構成した、Webページのアクセス・ログ(2.9Mバイト)
-
factbook.xml: XMLとして再構成した、CIA World Factbookのデータ(4.0Mバイト)
小規模な文書の集まりとしては、次のようなものです。
-
ants: Antビルド・ユーティリティ用のXML設定ファイル(18ファイル、合計100Kバイト)
-
fms: Freshmeat.netからのRDF文書(37文書、合計136Kバイト)
-
soaps: SOAP文書のサンプル(42文書、合計30Kバイト)
-
webs: Webアプリケーションの設定ファイル(70文書、合計132Kバイト)
それでは、結果を発表します!
図1から図3が、実際の検証結果を示しています。全体的にはgzip表現が他を圧倒して最も小さな出力サイズ(テキスト表現が8.0MB、gzipが1.3MB、XBISが4.1MB)になっており、平均圧縮率も6:1以上ですが、処理時間が他に比べて目立って長くなっています。gzip形式の処理のオーバーヘッドは、主に出力側にあり、入力はプレーン・テキストと同程度に高速です。ところがgzipの出力時間が入力時間よりも大幅に遅いため、全体としてのgzipコードの処理速度は、テキストの約1/3(つまり、実行時間は約3倍)で実行されることになります。
図1. 中規模文書に対する結果
XBISはテストした様々なサイズや形式の文書全体に渡って、素晴らしいパフォーマンスを見せています。全体的にはテキストよりも2倍以上速く、gzipよりも6倍以上高速です。テキストと比較しての圧縮率は比較的低く2:1ですが、それでも必要な帯域幅は大幅に小さくなります。
図2. 大規模文書に対する結果
小規模な文書の集合に対する結果を示した図3を見ると、gzip圧縮が小規模な文書よりも大規模な文書に対して、より効果的に動作することが分かります。それぞれの集合に含まれる各文書は、別々に保つ必要があるため、gzipを使ってそれぞれ個別に圧縮されます(XMLを使ったストリームでは、文書が明確に分離されていないため、複数の文書を一緒に混ぜることはできません)。図3に示す文書集合の合計サイズは、比較的小さいため、gzipエンコーディングが非効率であっても、全体的な結果にはほとんど影響を与えていません。
図3. 小規模文書の集合に対する結果
gzipの時間測定の結果はXMLを認識するバージョンのgzipを使うことで改善される可能性があります。これによりgzipでの入出力において、常に余分なステップ(XMLテキスト)を通す必要が無くなります。また、XMLを認識するバージョンのgzipがXMill(参考文献参照)のような技法の概念を採り入れることによって、XML文書をさらに圧縮できる可能性もあります。ただし、gzipがXBISに近いほどにまで高速化される可能性は低いようです。
XBISの利点
XBISは、テキストXMLの処理よりも有利な点をいくつか利用することによって、高速な処理を実現することができます。一つは、XMLテキストの持つ冗長性の多くを排除している点です。冗長性を減らすことによって、表現を短くすることができますし、同時に(特に入力における)処理も高速になります。もう一つの利点は、テキストXMLパーサが様々なエンコード方式をサポートするのと違い、文字データのエンコード方式を一つしか使わないという点です。エンコード方式が一つしか要求されないので、文字列のエンコード処理やデコード処理をXBIS処理の中に直接組み込むことができ、処理のために別のレイヤを必要としません。そして最後に、テキストXMLでは文字毎の状態変化の型式が数多くあり、その確認が重要ですが、XBISではその確認が必要ないのです。
一部の開発者は議論の中で、XBISが速度の点で有利なのは(パーサのような)XMLプロセッサで必要な整形式であるか否かの確認を実行しないためだと言っています。これは設計上ある程度正しいと言えます。けれども、XBISを構成する際に、整形式としてある種の問題がある文書はエンコードできないため、XBIS表現の文書を扱う時には整形式であるか否かの確認の大部分は必要ないのです。XBISエンコーダに対して(例えば要素名や属性名における無効な文字など)誤った入力を与えることによって、他の型式のエラーが生じる可能性はありますが、それを確認したとしても大きなオーバーヘッドにはならないでしょう。例えば要素名や属性名の場合であれば、名前はエンコードされた形式の文書に一度だけテキストとして書き込まれるのみであり、次に再度使われる時には、割り当てられた整数値で参照されます。従って最初に名前を扱う時に、名前に含まれている文字が適切な文字のみであることを容易に検証できます。XBISでは、他の種類の整形式であるか否かの確認を行う場合にも、同じ原理が当てはまります。
今後の動き
第1回で説明した通り、XMLデータの代替表現に対する関心は次第に高まっています。W3Cには、使用事例を調査し、測定方法を検討し、そしてテキストXMLに対する代替表現の標準(あるいは標準群)の開発も視野に入れた新しいワーキング・グループ(XML Binary Characterization Working Group)まで作られています。
そうした標準でどのような形式を採用するかは現在では全く分かりません。XBIS方式の手法は(構文の全てではありませんが)XML文書の意味を完全に維持するので、(第1回の「神聖なるデータ」の項で説明したように)幾つか有利な点があります。だたし、スキーマ・ベースのバイナリ・エンコーディングでは、表現がもう少しコンパクトになると同時に、入出力がずっと速くなる可能性があります。ここでの入出力は、テキストとバイナリ間の変換を省略することができるので、XBISよりもずっと高速になるでしょう。
こうした範疇の両方に適合するプロジェクトは、ANS.1 (Abstract Syntax Notation One)と関連して行われています。これはメッセージを抽象的に記述するための言語ですが、(バイナリ・エンコーディングに変換する規則を含めて)様々に異なった規則群のどれを使用してもエンコードすることができます。ASN.1は通信業界やその関連分野で広く使用されており、最近ではXMLと連携できるように変更されています。Fast Infoset と呼ばれるプロジェクトでは、XML文書の意味を完全に(あるいは少なくとも意味の大部分を)維持します。もう一つのプロジェクト Fast Schema (またはX.694)では、文書に対するスキーマからエンコードやデコードの規則を生成し、データを直接エンコード形式に持って行きます。今のところ、ASN.1の作業に関して公開されている情報や検証可能な情報はほとんどありませんが、これはやがて改善されるでしょう。
スキーマに基づくバイナリ・エンコーディングは、データ・オブジェクトと実際にエンコードされた形式との間で変換のレイヤを通過する必要があるため、(公開で議論されているASN.1の実装を含めた)既存の方法の中では、その潜在力が完全には利用されていないようです。これに対して、私の行っているJiBXデータ・バインディング・フレームワーク(参考文献参照)で実装しているような、クラス拡張技法を適応させることは可能でしょう。JiBXでは、XMLとオブジェクト間の変換コードをクラス・ファイルに直接埋め込むような実装を行うことによって部分的に非常に高いパフォーマンスを得ることができます。これと同じ手法をバイナリ・エンコーディングに適用することによって、クラスはエンコーディングとの間で自分自身を効果的にシリアル化できるようになります。この型式の実装を使うことによって、等価なデータに対して少なくともXBISよりも数倍速いパフォーマンスが得られると私は思っています。
スキーマに基づくバイナリ・エンコーディングを使うことによって必然的にテキストXMLとの互換性が失われますが、それに見合うパフォーマンスは得られるのでしょうか?・・・これは幾つものやっかいな問題に絡んでくる質問です。例えば、スキーマからバイナリ・エンコーディングを生成するという手法は、しばしば、Webサービスとの関連で議論されます。ところがWebサービスの将来においてセキュリティがより一層重要な役割を果たすと思われますが、バイナリ・エンコーディングは、一般的にWebサービス分野でのセキュリティ標準の基礎となっているXML Canonicalizationの原則を破ってしまいます。XML文書の完全な意味を維持するXBIS方式の手法はパフォーマンスの改善余地は少ないのですが、Canonicalization(正規化)やその他の標準とは協調できます。こうした理由から、両方の型式の手法が組み合わされて使われる可能性が高いように思えます。
まとめ
この検証結果から、データ・サイズと処理のオーバーヘッドという両面で、XMLに対してテキスト以外の表現を使うことが非常に有利なことが分かります。標準的なテキスト圧縮技法では、処理のオーバーヘッドは大きくなりますが、文書サイズは劇的に小さくなります。XBISのようなXML専用のエンコーディングでは、処理のオーバーヘッドは大幅に少なくなり、かつ文書サイズもある程度小さくなります。特定の文書構造に合わせて調整されるスキーマ・ベースのエンコーディングは、交換される文書型式が既知のものに限られる場合においては、将来さらに高いパフォーマンスを発揮することになるでしょう。
残念ながら、処理のオーバーヘッドを減らすことができるようなエンコード方式は、まだ標準化されていません。そうしたものが現れるまで、XML処理のオーバーヘッドを減らす必要のあるアプリケーションは、独自の方策を考えるしかありません(そうしたアプリケーションが既に存在しているとしての話です。多くのXMLの専門家は、そういうものはまだ無いと言っています)。当面そうしたアプリケーションは、現在開発中のエンコード方式のどれかを使うことにするか、あるいは完全にXMLを回避して、データに独自な直接のエンコード方式を生成する他はありません。どちらも気の進まない選択と言えます。ですから皆さんがこの選択をする立場に置かれたなら、この分野で活動しているグループの中の一つ(例えば参考文献にあるW3CのXML Binary Characterization Working Groupなど)に意見を持って参加すべきかも知れません。
参考文献
- オープン・ソースの
XML Binary Information Set (XBIS) プロジェクトをダウンロードしてください。これは、著者自身が行っている速度を最適化するXML表現です。XBIS(xbis-0.9.5 リリース)には、コードとこの記事のテスト・データが含まれており、XBIS downloads ページから入手できます。
-
XML Binary Characterization Working Group についてさらに学んでください。このグループは、テキストXMLの代替としてのバイナリ・エンコーディングの使用事例を調査するために、W3Cが設立したものです。このグループは、直接ある種の標準を作るべく意図された活動ではありませんが、この分野での懸念事項や必要性を訴える場としてはおそらくpublic mailing list が適切でしょう。
- 効率的なXMLの圧縮についてさらに学んでみたいのであれば、手始めとして優れたDavid MertzによるXMLの論考コラム「XMLと圧縮」(developerWorks, 2001年9月)と「続・XMLと圧縮」(developerWorks, 2002年4月)があります。
- Webサービスの作業にXML圧縮を直接適用する方法について、「SOAPを搾る」を調べてみてください(developerWorks, 2003年3月)
- 同じ著者による「XML転送のパフォーマンスを改善する 第1回」(developerWorks, 2004年6月)で、XMLのテキスト表現と代替表現にまつわる問題の背景について学んでください。
-
ASN.1 Information Site で、Abstract Syntax Notation One (ASN.1)標準について学んでください。ここでは(非常にASN.1寄りですが)XMLに関連したASN.1の作業の要約を説明しています。「Fast Infoset」は、ASN.1ベースの手法ですが、XMLデータの取り扱い方に関してはXBISに似ています。一方「Fast Schema」(Sunによる「Fast Web Services」プロジェクトの一部)は、XMLスキーマの変換に基づいてデータをカスタム・バイナリ表現するところまで踏み込んでいます。
- 通常のテキストXMLとJavaオブジェクトの間での高速変換を探しているのであれば、著者によるJiBX Data Binding が良いかも知れません。生成されたバイトコードを使ってクラスを拡張する、高速で柔軟性のあるバインディングであり、XMLとの間でやり取りできるようになります。
- 別々のテキスト形式を持つ2つのXML文書が、どういう場合に本当に等価なのか判断が付かないのであれば、Canonical XML 勧告がその質問に答えられるように作られています。
- 実質的にXMLを完全に回避するスキーマ・ベースのエンコーディングの例として、Fast Web Services について読んでみてください。
- developerWorksのXMLゾーン には、XML関連の資料が豊富に用意されています。
- developerWorksのDeveloper Bookstore には、XML関連の書籍が豊富に揃っています。
- XMLおよび関連技術においてIBM認証開発者になる方法についてはこちら を参照してください。
著者について  | 
|  | Dennis Sosnoskiはシアトル地域にあるJava技術のコンサルティング会社、Sosnoski Software Solutions, Inc.の創立者で、主席コンサルタントでもあり、またXMLやWebサービスに関するトレーニングやコンサルティングの専門家でもあります。彼のプロとしてのソフトウェア開発経験は30年以上に渡り、ここ数年はサーバー側のXML技術やJava技術に注力しています。Dennisは、全米各地で行われる会議で頻繁に講演を行っています。また、Javaクラスワーキング技術を基に構築された、オープンソースのJiBX XML Data Bindingフレームワークの中心開発者でもあります。
|
記事の評価
|