目次


XML転送のパフォーマンスを改善する 第1回

XML文書を転送する上での帯域幅と処理との兼ね合い

Comments

データ交換用にXMLの使用が増え続けているということは、アプリケーション間で送信されるXML文書の数や量もそれに合わせて増え続けていることを意味します。この傾向は、将来的にも変化する兆候は見られません・・・むしろ、XMLベースのWebサービスがより広範にサポートされ、利用されるようになるにつれて、より一層発展するでしょう。これだけの成功を収めていることは、XMLが広範囲のアプリケーションに渡って有用なものであることの確かな証しだと言うことができます。

どのような設計でも同様ですが、XMLにも多少弱点があります。その一つは、アプリケーション・データからXML表現に変換したり、XML表現からアプリケーション・データに変換したりする際の(サイズと処理時間の両面における)オーバーヘッドです。このオーバーヘッドは、多くのアプリケーション(特に比較的小さな内部処理で大量のデータを交換するようなアプリケーション)において、全体の処理コストに対して大きな割合を占めることになります。こうした種類のアプリケーションでもXMLの持つ利点の多くは相変わらず有効ですが、コストもまた高くなってきます。こうしたコストのために、開発者は大容量のデータ交換にXMLを使用すべきか否かに関して、より慎重に検討するようになっています。

代替手段として最近次第に注目を集めるようになっているのが、XMLの構造を維持しつつ効率を上げるために非テキスト表現を使用するものです。この記事では、XMLの非テキスト表現にまつわる問題と、このような目的で開発されている手法の幾つかを取り上げます。 第2回 (US)では、どの程度の改善が可能なのか、その度合いの感覚をつかめるように、実際のパフォーマンス測定を行う予定です。

文書サイズ

データをXMLで表現すると、同じデータをバイナリで表した場合に比べて非常に大きなものになりがちですが、これには主に2つの理由があります。

  1. 一般的に単純なデータ値をテキストで表すと、同じ値をバイナリで表した場合よりも大きくなります。極端な例として、1バイトのバイナリ値を符号付きの整数テキスト値(例えば「0」、「18」、「-128」など)として表すには、1から4文字が必要になります。
  2. XMLは簡潔さではなく、明快さと相互運用性のために設計されたテキスト・マークアップの形式です(XML勧告「1.1 経緯及び目標」にあるように、「XMLでは、マーク付けの数を減らすことは重要ではない」のです)。これを実際的なレベルの例で示すと、どの開始タグにも必ず対応した終了タグが必要であるということに現れています。XMLアプリケーションでしばしば使用されるような長い要素名や属性名と、この冗長性が組み合わされると、XML文書のマークアップ要素のサイズが、実際の文書のデータ要素のサイズを優に超えることになります。単に体裁を良くする目的で追加された空白(XMLで要求されるわけではありませんが、XMLの明快さを強調するためによく使用されます)によって、文書がより一層かさばったものになります。

文書サイズが大きいということは、等価なバイナリ表現のデータを転送する場合に比べて、XML表現のデータを転送するためには、より広い帯域幅が必要になる、ということを意味します。通信処理に関わるオーバーヘッドの大部分がデータ量に基づくため、サイズが大きいと処理コストも大きくなることを意味しています。

処理のオーバーヘッド

XMLにはまた、単純なバイナリのデータ表現よりも多くの処理のオーバーヘッドが伴います。XML文書プロセッサは、入力側で文書の文字入力中に、それぞれ異なる形式のマークアップを表すような、幾つかの形式の文字の組み合わせを認識する必要があります。またプロセッサは、各文書が整形式のXMLであることを検証する必要があるので、マークアップを処理しながら状態遷移も確認する必要があります。名前空間の使用は任意ですが、次第に一般的になっており、名前空間の定義とそれに関連した接頭辞の追跡と、マークアップ中の要素名と属性名の双方で使用される接頭辞の識別と参照が必要になります。そして最後に、受信側のアプリケーションによって、利用し易いように、テキストのXMLデータをある型のバイナリ値に変換する必要があるかもしれません。

XML文書の出力にも同じような問題があります。バイナリ・データは、最初にテキスト表現に変換する必要があります。文字データに実体を使って表現する必要のある値が無いか確認する必要があり、全ての型のデータを出力するためにマークアップを構成し、出力に追加する必要もあります。名前空間を使用する場合には、マークアップで使用された要素名や属性名についても、名前空間URIや適切なURIを意味する接頭辞が無いか確認する必要があります。

XML文書のテキストに使用される特定の文字エンコーディングには、変換が必要となり、このため入出力共に複雑なものになります。XMLプロセッサは、通常使用される可能性のある多種多様なエンコーディングで動作するように設計されています。ですから、2つのアプリケーション間での文書交換において、常にあらかじめ決められた特定のエンコーディングが使用される場合であっても、そのアプリケーションは相変わらず汎用的な処理のためにオーバーヘッドを抱えることになるでしょう。

テキストの枠を超えて

XMLはテキストでのみ定義されるので、厳密に言えばテキスト以外のものはどれもXMLではあり得ないことになります。一方データ交換にXMLを使用するアプリケーションでは、厳密なXML表現よりも転送されるデータの方に関心があるかも知れません。XMLの持つテキストであると言う本質をどの程度守るかによって、文書サイズを小さくしたり、処理スピードを高めたり、あるいはその両方を実現するような様々な技術があります。この章では、こうした技術のうち、3つの種類について説明します。

  1. 汎用のテキスト変換
  2. XMLのために特に設計されたエンコーディング
  3. 特定のXMLアプリケーション用に調整されたフォーマット

神聖なるテキスト: 汎用のテキスト変換

XMLの持つテキストであると言う本質に最も厳密なレベルで適合しているのが、汎用のテキスト・ベースでの変換です。この形式の変換は、主に文書サイズに関係してきます。テキストの圧縮アルゴリズムは、長年に渡って広範囲な研究対象となっており、開発段階としては非常に進んだところにあります。この形式のアルゴリズムはどれも、XML文書のテキスト表現に対して容易に適用することができます。ただし、こうしたアルゴリズムは、通常のXMLのテキスト処理以外にアプリケーション間でのデータ授受のそれぞれの終端に実質的にもう一つの変換層(送り側でテキストを圧縮し、受信側で解凍する)を追加することになるので、処理速度を改善する可能性は低いと言えます。

gzipアルゴリズムは、テキスト文書の圧縮用に広く使用されている標準の一つであり、標準のJavaライブラリを含めて様々なプラットフォームで実装されています。第2回では、選択肢の一つとしてgzipを含めたJavaベースのパフォーマンス・テストの結果を説明する予定です。

教えを守る: XMLのために特に設計されたエンコーディング

実際に意味があるXML文書のテキストを全て保持しつつ、汎用のテキスト・ベースの変換以上のことを行うこともできます。この形式の手法は、XML文書の構造を利用した何らかのコード化表現によって、文書サイズあるいは処理のオーバーヘッドを減らすように意図されています。例えば、どのようなXMLプロセッサであっても、属性間の空白数や属性値の前後に使用される引用符の種類、それに属性の順序など・・・は、無視されるので、XMLには無関係の情報を失うだけで、コード化した形式から元の文書を再構築することは一般的に可能です。情報が失われるため、元の文書と再構築された文書とを直接テキスト比較すると失敗するかも知れませんが、XMLの規則に従うアプリケーションであればどんなものから見ても、2つの文書は同じように見えるはずです。

文書のXMLビュー(XML文書が本来目的とする情報)を維持するような変換をここでは、XMLエンコーディング(XML encoding)と呼ぶことにします。XMLの変換がXMLエンコーディングであるためには、任意の妥当なXML文書に対して、完全なXMLビューを保存できる必要があります。これを一般的に証明することは困難ですが、XML Canonicalization 勧告では現実的な検証方法が提供されています。ここでは、複数の文書が論理的に等価であるかどうかを判断するために、XML文書を標準形式に変換する方法を詳細に説明しており、XMLデータを保証したり、XMLデータに署名したりするための多くの取組みの基礎となっています。エンコーディングへの入力文書の正規化形式が、常に再構築された文書の正規化形式と同じである場合に限り、またそれが成り立つのであれば、XMLデータを表現するその技術をXMLエンコーディングである、と言っても差し支えないでしょう。もし正当な文書に対して、この手法を使って検証した結果、失敗するのであれば、その技法はXMLエンコーディングと見なすことはできません。

XMill(参考文献参照)は、文書サイズを小さくするために設計されたXML変換の良い例です。XMillはgzip圧縮との組み合わせで動作し、基本的には文書テキストを、より圧縮できるように再配置します。これには幾つかのステップがあります。最初に実際の要素の開始タグと終了タグを整数値に置き換え、これだけで圧縮されます。次に、ある型の全要素に対する文字データがひとまとめにされ、別々に圧縮されます。この2番目のステップは、各型の要素に対して繰り返されます(XMillでは各型の要素もカスタマイズすることができるのですが、今はその点を無視することにします)。この方法で類似のデータを分類することにより、gzipがより効率的に動作します。最終的な結果として、gzip単体で行ったのと同程度の処理コストで、サイズはより小さく圧縮されたものになります(そして全体としては、より少ない処理となる可能性があります)。先ほどの段落の意味合いにおいて、XMillが真のXMLエンコーディングかどうかは、実はその説明を読んでも明確ではありませんが、確かに一つの方法だと言えるでしょう。

他の手法を使うことによって、テキストXMLの文書処理よりも高い速度を得ることもできます。一般的にこうした高速手法は、XML文書の冗長性を一部除去しつつ、同時にXML文書を処理し易くするような方法に基づいています。これは矛盾しているように聞こえるかもしれません。冗長性を除去すると文書が処理しにくくなるはずで、簡単にはならないように思えますが、実際にはこの2つの目標は相性が良いのです。両方の目標に適う変換の例として、終了タグの代わりにカウントやマーカを使って要素や属性名を簡潔な表現に置き換え、(例えば属性値の周りの="..." 文字など)典型的なテキスト・パターンをなくす方法や、場合によっては繰り返される文字データの内容を再利用するなどの方法があります。

私自身が取組んでいるオープン・ソースのXML Binary Infoset (XBIS)プロジェクト(参考文献参照)では、先ほどの段落で述べた全ての変換を組み合わせ、また文書の構成要素を効率的にパックしたバイト表現を使うことによって、文書のXMLビューを保つように設計したエンコーディングを定義しています。XBISの焦点は、文書サイズよりも処理スピードですが、処理が速くなると同時に、一般的にテキストと比較して大幅なサイズ削減も可能となります。私が検証した全てのXML文書で正規化形式を保つ、という意味合いにおいてXBISは完全なXMLエンコーディングです(もしかすると、将来この方式で失敗するような、変わった文書に出くわすかも知れません。その場合には、足りなかった情報がどんなものであれ、XBIS表現に追加するつもりです)。

XBISとXMillは(要素名を数値に置き換えることを含めて)多少似ているところもありますが、前者は後者と非常に異なった手法を使っています。XMillは本質的に(gzip自体と同様に)文書の全てを変換します。つまり文書の全テキストを一度に処理する必要があるのです。これはXMill表現へのエンコード、XMill表現からのデコードの両方に当てはまります。ですからXMill(またはgzip単体)では、システム間で転送される文書の処理に対して、潜在的に反応時間に遅延が加わる可能性があります。一方XBISは、エンコードもデコードもその場で行うことができるストリーミング変換なのです。これは、文書サイズに焦点を当てるXMillに対して、速度に焦点を当てるXBISとの相違と矛盾していません。サイズが主な関心事であれば、多少の遅延や処理のオーバーヘッドが生じたとしてもサイズを最小限に縮小することには意味があります。ところが速度が主な関心事であるならば、速度の妨げになるものは最小限にとどめ、何事も動作させながら処理する方が一般的に良いということになります。

XMLエンコーディングは、テキスト文書にgzipを使うのと論理的に等価であると私は個人的に思っています。ただし、誰もが私と同意見というわけではありません。高い評価を得ている一部のXML開発者にとっては、(たとえXMLには無関係な方式であっても)文書のテキスト表現を変更するような転送形式はどんなものでも、その文書を歪めるものなのです。こうした開発者にとってgzipは、元の文書が完全かつ厳密に再構成できるので許容範囲内ですが、テキストをそのまま保持しないようなXMLエンコーディング手法は、どんなものであれ許されないのです。プレーン・テキストあるいはテキスト・ベースの圧縮に代わる手段を検討しているプロジェクトに取組んでいる開発者にとって、これは考慮すべき問題と言えるでしょう。

神聖なるデータ: 特定のXMLアプリケーション用に調整されたフォーマット

特定のXMLアプリケーションのために特に設計されたフォーマットは、テキスト・ベースの圧縮の対極にあるものです。こうしたフォーマットは、データを純粋にバイナリ表現したものと等価であり、テキストXMLと比較してデータ・サイズの減少と処理のオーバーヘッドの排除との両方を実現できる可能性があります。この方式の主な欠点は、アプリケーションが使用する文書構造に合わせて調整が必要であり、厳密な構造に関して送信側、受信側双方が事前に合意し、適切なエンコーダ/デコーダを実装する必要がある・・・、という点です。

アプリケーションに合わせてエンコードを調整するために使用する手法の多くは、文書の交換が可能なようにW3C XML Schema仕様に基づいています。スキーマに盛り込まれた 型 や 構造 に関する情報は、文書のデータ内容を表わすことができ、(場合によっては、エンコーダ/デコーダで直接動作するオブジェクトを含めた)専用のエンコーダ/デコーダのコードを生成するために使用されます。Fast Web Services(参考文献参照)による手法は、スキーマに基づいて調整されたエンコードの一例であり、ASN.1構造化データ記述の上に構築されています。

この方式のスキーマのコード化(Schema encoding)と、一般的なXML文書(同じ型式である場合も、そうでない場合もあり、またスキーマがある場合も無い場合もあり得ます)を操作する他の選択肢とを比較することは困難です。多岐に渡る文書を検証するためには、各文書に対してスキーマを定義し、次にそのスキーマに対するエンコーダ/デコーダのコードを生成する必要があります。現在の実装では、データ表現から標準的なXMLテキスト形式に変換したり、逆に標準的なXMLテキスト形式からデータ表現に変換したりすることは、一般的に可能ではありません。ですから標準的なテキストXML文書からエンコーディングが使える形式に変換するような、何らかの形の特別なコンバータも書く必要があります。こうした理由から検証結果の中には、この手法での例を含めていませんが、結果を示した後でスキーマのコード化の使い方に関してコメントを追加する予定です。

まとめ

ここまででXMLの非テキスト表現に関する、なぜ・・・、どうやって・・・、という背景を説明しながら基本的なところは説明しましたので、次回は達成可能な利点を中心に説明を続けます。第2回では、多岐に渡る文書に対して、どのようにテキスト表現やgzip表現、それにXBIS表現を検証したかを説明し、その検証結果を示しながら説明を加えた後、この分野で継続的に行われている活動の幾つかを紹介して締めくくるつもりです。


ダウンロード可能なリソース


関連トピック

  • 効率的なXMLの圧縮についてさらに学んでみたいのであれば、手始めとして優れたDavid MertzによるXMLの論考コラム「XMLと圧縮」(developerWorks, 2001年9月)と「続・XMLと圧縮」(developerWorks, 2002年4月)があります。
  • Webサービスの作業にXML圧縮を直接適用する方法について、「SOAPを搾る」を調べてみてください(developerWorks, 2003年3月)。
  • 別々のテキスト形式を持つ2つのXML文書が、どういう場合に本当に等価なのか判断が付かないのであれば、Canonical XML 勧告がその質問に答えられるように作られています。
  • 実質的にXMLを完全に回避するスキーマ・ベースのエンコーディングの例として、Fast Web Services について読んでみてください。
  • developerWorksのXMLゾーン には、XML関連の資料が豊富に用意されています。
  • developerWorksのDeveloper Bookstore には、XML関連の書籍が豊富に揃っています。
  • XMLおよび関連技術においてIBM認証開発者になる方法についてはこちら を参照してください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=242732
ArticleTitle=XML転送のパフォーマンスを改善する 第1回
publish-date=06042004