JavaにおけるXML: データ・バインディング 第2回 パフォーマンス

第1回を簡単に振り返ってから、データ・バインディング・フレームワークをテストしよう

エンタープライズJavaの専門家であるDennis Sosnoski氏が、JavaのXMLデータ・バインディング用の各種フレームワークの処理速度とメモリー使用量をチェックします。このテストには、第1回の記事で取り上げたコード生成方式のすべてのデータ・バインディング、それより前の記事で取り上げたCastorのマッピング方式によるデータ・バインディングのほかに、今回初めて取り上げるフレームワークを1つおまけとして含めています。普段からJavaアプリケーションでXMLを処理している方であれば、これらのデータ・バインディング方式が出したパフォーマンス結果を見逃すわけにはいかないでしょう。

Dennis Sosnoski, President, Sosnoski Software Solutions, Inc.

Dennis Sosnoski はシアトル地域にある Java 技術のコンサルティング会社、Sosnoski Software Solutions, Inc. の創立者で、主席コンサルタントでもあり、また XML や Web サービスに関するトレーニングやコンサルティングの専門家でもあります。彼のプロとしてのソフトウェア開発経験は 30年以上に渡り、ここ数年はサーバー側の XML 技術や Java 技術に注力しています。Dennis は、全米各地で行われる会議で頻繁に講演を行っています。また、Java クラスワーキング技術を基に構築された、オープンソースの JiBX XML Data Binding フレームワークの中心開発者でもあります。



2003年 1月 01日

第1回の記事では、XMLデータ・バインディングを使用する場合の条件や、データ・バインディング用の各種Javaフレームワークの概要を示しました。第1回をまだお読みでなければ、とりあえずざっと目を通してみてください。今回は、条件や使用法についてさらに詳しく書くよりも、パフォーマンスの話にすぐに移りたいと思います。

パフォーマンス・テスト

データ・バインディング・フレームワークのパフォーマンス・テストのために、架空の航空会社のフライト・スケジュール情報を記述した文書を作成しました。これらの文書は、Castorのマッピングによるデータ・バインディングを取り上げた以前の記事(参考文献を参照) で作成した文書と同じ構造になっています。その構造のサンプルを以下に示します。主に属性としてデータ値を記述した形式なので、ここでは「簡略」形式を呼ぶことにします。

リスト1. 簡略形式の文書
<?xml version="1.0"?>
<timetable>
  <carrier ident="AR" rating="9">
    <URL>http://www.arcticairlines.com</URL>
    <name>Arctic Airlines</name>
  </carrier>
  <carrier ident="CA" rating="7">
    <URL>http://www.combinedlines.com</URL>
    <name>Combined Airlines</name>
  </carrier>
  <airport ident="SEA">
    <location>Seattle, WA</location>
    <name>Seattle-Tacoma International Airport</name>
  </airport>
  <airport ident="LAX">
    <location>Los Angeles, CA</location>
    <name>Los Angeles International Airport</name>
  </airport>
  <route from="SEA" to="LAX">
    <flight carrier="AR" depart="6:23a" arrive="8:42a" number="426"/>
    <flight carrier="CA" depart="8:10a" arrive="10:52a" number="833"/>
    <flight carrier="AR" depart="9:00a" arrive="11:36a" number="433"/>
  </route>
  <route from="LAX" to="SEA">
    <flight carrier="CA" depart="7:45a" arrive="10:20a" number="311"/>
    <flight carrier="AR" depart="9:27a" arrive="12:04p" number="593"/>
    <flight carrier="AR" depart="12:30p" arrive="3:07p" number="102"/>
  </route>
</timetable>

なお、リスト1 の空港名の情報は、通常は1行で書くところですが、コラム・サイズに合わせて2行に分けてあります。

簡略形式の文書とは別に、主に子要素としてデータ値を記述した文書も作りました(属性として残したのはIDとIDREFだけです)。その形式のサンプル文書を以下に示します(ここでは「詳細」形式と呼ぶことにします)。

リスト2. 詳細形式の文書
<?xml version="1.0"?>
<timetable>
    <carrier ident="AR">
        <rating>9</rating>
        <URL>http://www.arcticairlines.com</URL>
        <name>Arctic Airlines</name>
    </carrier>
    <carrier ident="CA">
         <rating>7</rating>
       <URL>http://www.combinedlines.com</URL>
        <name>Combined Airlines</name>
    </carrier>
    <airport ident="SEA">
        <location>Seattle, WA</location>
        <name>Seattle-Tacoma International Airport</name>
    </airport>
    <airport ident="LAX">
        <location>Los Angeles, CA</location>
        <name>Los Angeles International Airport</name>
    </airport>
    <route from="SEA" to="LAX">
        <flight carrier="AR">
          <number>426</number>
          <depart>6:23a</depart>
          <arrive>8:42a</arrive>
        </flight>
        <flight carrier="CA">
          <number>833</number>
          <depart>8:10a</depart>
          <arrive>10:52a</arrive>
        </flight>
        <flight carrier="AR">
          <number>433</number>
          <depart>9:00a</depart>
          <arrive>11:36a</arrive>
        </flight>
    </route>
    <route from="LAX" to="SEA">
        <flight carrier="CA">
          <number>311</number>
          <depart>7:45a</depart>
          <arrive>10:20a</arrive>
        </flight>
        <flight carrier="AR">
          <number>593</number>
          <depart>9:27a</depart>
          <arrive>12:04p</arrive>
        </flight>
        <flight carrier="AR">
          <number>102</number>
          <depart>12:30p</depart>
          <arrive>3:07p</arrive>
        </flight>
    </route>
</timetable>

各種XMLフレームワークの相対的なパフォーマンスは、使用する文書のサイズによって大きく異なる場合が多いので、今回のパフォーマンス・テストには大きな文書と小さな文書を両方含めることにしました。大きな文書(time-comp.xmltime-full.xml) では、上記の2種類の形式と同じデータ値を使っています。そのため、両者のサイズにはかなりの差があります(簡略形式が106 KB、詳細形式が211 KB)。一方、小さな文書は小分けにしてあり、簡略形式では1.4~3.3 KBのサイズの34文書のコレクション (ttcomp)、詳細形式では2.2~5.8 KBのサイズの34文書のコレクション (ttfull) になっています。大きな文書と同じく、小さな文書コレクションのそれぞれ対応する文書には、同じデータ値を記述しています。今回のテストで使用した文書のフルセットをダウンロード・ページに用意しておきました(参考文献を参照)。

データ・バインディングの用語

以下は、この記事で使っている用語のミニ辞典です。

マーシャリングとは、メモリー内のオブジェクトのXML表現を生成する処理のことです。Javaオブジェクトの直列化と同じように、そのXML表現にはすべての依存オブジェクトを組み込む必要があります。つまり、メイン・オブジェクトから参照されているオブジェクトや、その参照されているオブジェクトからさらに参照されているオブジェクトなどをすべて組み込まなければなりません。

アンマーシャリングとは、マーシャリングの逆の処理であり、XML表現からメモリー内にオブジェクトを(場合によってはリンク先オブジェクトのグラフ構造も) 生成します。

マッピング とは、オブジェクトとXML文書との間の明示的なマーシャリング /アンマーシャリングに使用する規則のセットです。文書のDTD記述またはW3CのXML Schema記述に基づくコード生成方式のデータ・バインディングでは、基本的に、生成されるオブジェクトに暗黙のマッピングが組み込まれるので、この記事では、ユーザー定義のJavaオブジェクトとXML文書との対応関係に限ってこの「マッピング」という表現を使っています。

今回はこの2種類の形式の文書でテストを実施しましたが、本来ならもっと多くの種類の文書を使いたいところです。しかし、このようなデータ・バインディングのテストで多種多様な文書を使おうとすると、コード生成方式ではW3CのXML Schema (以降、「Schema」) 記述と文書型定義 (DTD) 記述、マッピング方式ではマッピング・ファイルと基本クラスをそれぞれに用意しなければならなくなり、とんでもない手間がかかってしまいます。とりあえず2種類の形式にそれぞれ大小の変化をつけることで、典型的なビジネス文書を対象にした場合のデータ・バインディングの各種の手法について、かなり正確なパフォーマンス結果を導き出せると思います。ただし、マッピング方式のデータ・バインディングに関しては、メモリー使用量の結果を多少差し引いて考える必要があるかもしれません。今回の文書で使っているデータ値のほとんどはプリミティブなデータ型に変換できるので、非常にコンパクトな内部表現に圧縮できるのに対し、ほとんどのデータ値をString としてそのまま保持しなければならない文書では、メモリー・パフォーマンスが低下してしまうからです。

今回のすべてのテストに使用したシステムは1.4GHzのAthlonで、DDR RAMが256MB、OSがRedHat Linux 7.2という環境です。また、SunのJDK 1.4.1 for Linuxをすべてのテストで使用しました。テストの対象になった各種データ・バインディング・フレームワークのバージョンは、JAXB Beta 1、Castor 0.9.4.1、JBind 1.0 Beta 12/07、Quick 4.3.1、Zeus Beta 3.5です(なお、JiBXをおまけとして追加しました。詳細については、テスト結果の後に載せたJiBXって何物?をご覧ください)。JBindとJiBX以外のテストでは、Piccolo SAX2パーサーのバージョン1.0.3を使用しています。これは私の知る限り最速のSAX2パーサーであり、JiBXのテストに使用したXMLPullパーサー (XPP3バージョン1.1.2)の処理速度に匹敵するか、場合によってそれを上回っています。JBindについてはPiccoloパーサーに対応していないので、Xerces Java 2バージョン2.2.0を使用しました。

さらに、データ・バインディングの手法とその他の手法のパフォーマンスを比較するために、同じファイルを対象にして、SAX2パーサーだけを使った速度テストや、dom4j文書モデルを使った速度テストとメモリー・テストも実施しました(dom4jは、文書モデルの中でもパフォーマンスが最も優れており、入力文書の解析にさまざまなSAX2パーサーを使用できます)。なお、テストに使用したdom4jのバージョンは1.3です。

今回の処理速度とメモリー使用量のテストに使った基本フレームワークは、文書モデルに関する以前のテストに使ったものと同じです(参考文献では、文書モデルのパフォーマンスに関する私の記事も紹介しています)。このベンチマーク・フレームワークは、内部のメモリー・バッファーにまずすべての文書を読み込んでから、それらの文書に対する入力操作と出力操作を何度か繰り返して速度を計測します。入力速度出力速度に示したテスト結果は、何度か繰り返した操作の中での最高タイムです。同じコードを反復実行するサーバー・タイプの環境では、その値が、長期的な観点から見た典型的なパフォーマンスになると思います。

入力速度

dom4j文書モデルとデータ・バインディングの各種の手法を使った場合に、XML文書を読み込んで(データ・バインディングの用語で言えば「アンマーシャリングして」)、メモリー内表現を構築するのにかかった時間を、図1 と図2 にまとめました。一番左に挙げておいたSAX2のタイム値は、文書の解析にかかる基本時間と見なせます。各種の文書モデルとデータ・バインディング実装は、その解析結果に基づいてメモリー内表現を構築するわけなので、それらの処理タイムがパーサー自体の処理タイムよりも短くなることはあり得ません。そのうち、2つのデータ・バインディング・テストは、コード生成方式ではなくマッピング方式に基づいています(図の中で「map」と書き添えてあるのがそれに当たります)。

図1. 大きな文書をメモリーに読み込むのにかかった時間 (単位はミリ秒)
図1. 大きな文書をメモリーに読み込むのにかかった時間 (単位はミリ秒)
図2. 小さな文書をメモリーに読み込むのにかかった時間 (単位はミリ秒)
図2. 小さな文書をメモリーに読み込むのにかかった時間 (単位はミリ秒)

dom4jの場合は、文書のメモリー内表現を構築するのに、パーサーだけの処理時間の2倍以下の時間しかかかっていません。これよりも優れた結果を出したデータ・バインディング・フレームワークはJiBXだけです。JAXB、Quick、Zeusはいずれも、dom4jと比較すればまずまずの結果を残していますが、JiBXのほぼ2倍の時間がかかっています。また、Castorについて言えば、マッピング方式でもコード生成方式でも処理がそれ以上に遅くなっているのが分かります。

JBindにいたっては、他のデータ・バインディング・フレームワークに大きく引き離されてしまいました。この遅さの原因としては、他のテストに使ったパーサーがJBindに対応していないため、ここでは遅いパーサーを使ったということがまず挙げられます。ただし、これは小さな要因です。もう少し大きな要因は、JBindが入力時にSchema記述に照らして文書を必ず妥当性検証するという点にあるかもしれません。これはかなりの時間ロスになります。しかし、最大の原因は、なんといってもJBindフレームワークの発想そのものでしょう。つまり、データ・バインディングの方法があまりにも回りくどいということです(現在の実装では、DOM文書モデルの上に対応関係を構築するという形になっています)。

ちなみに、JBind以外については、完全な妥当性検証をオフにしてテストを実施しました。データ・バインディング・フレームワークのほとんどには、その設計上必然的に行われるべきレベルの検証機能(要素の内容モデルが正しいことを確認する機能など) が用意されています。また、ほとんどのフレームワークは、入力時に文書の完全チェックを実行するために、妥当性検証機能を持ったパーサー (Xerces Java 2など) を使用できますし、中には、メモリー内に読み込んだバインディング済みのデータについて完全な検証を実行できるフレームワーク(JAXBなど) もあります。いずれにしても、今回のテストの目的はパフォーマンス測定なので、可能な場合にはオプショナルな検証機能をオフにしたわけです(たとえば、Castorでプロパティー・ファイルとマーシャリング /アンマーシャリング設定の両方を使用するようなこともしていません)。

出力速度

dom4j文書モデルとデータ・バインディングの各種の手法を使った場合に、メモリー内表現からXML直列化テキストを生成する(データ・バインディングの用語で言えば「アンマーシャリングする」)のにかかった時間を、図3 と図4 にまとめました。比較しやすいように前の図と同じ単位区分を使っていますが、SAX2パーサーのグラフがない点が違っています。

図3. 大きな文書をメモリーから書き出すのにかかった時間 (単位はミリ秒)
図3. 大きな文書をメモリーから書き出すのにかかった時間 (単位はミリ秒)
図4. 小さな文書をメモリーから書き出すのにかかった時間 (単位はミリ秒)
図4. 小さな文書をメモリーから書き出すのにかかった時間 (単位はミリ秒)

今回は、dom4jがすべてのデータ・バインディング手法よりも優れたパフォーマンス結果を出しました。その後にわずかの差でJiBXが続き、さらにその少し後にZeusが続いています。その他のデータ・バインディング・フレームワークは、ほぼ2倍以上の時間がかかっています。中でも一番遅かったのはQuickです(「Quick = クイック」が一番遅かったというのは事実であり、「だじゃれ」を言うつもりで書いているのではありません。念のため)。今回は、入力テストに比べて差がそれほど大きくなりませんでした。ただし、すべてのデータ・バインディング・フレームワークよりもdom4jのほうが速かったということは、やはりすべてのデータ・バインディング・フレームワークに改善の余地があることを示しています。

メモリー使用量

パフォーマンスのもう1つの面として、メモリー使用量の結果をまとめたのが、図5 と図6 です。文書モデルの場合、文書が非常に大きくなると (通常は5 MB以上になると)、メモリー不足が問題になる可能性が出てきます。文書表現に比べて、データ・バインディングの各手法は、メモリー使用量に関してどんな結果を出したのでしょうか。

図5. 大きな文書のメモリー使用量 (単位はKB)
図5. 大きな文書のメモリー使用量 (単位はKB)
図6. 小さな文書のメモリー使用量 (単位はKB)
図6. 小さな文書のメモリー使用量 (単位はKB)

この場合は、処理速度のパフォーマンスに比べてそれぞれの差が大きく広がっており、しかも傾向がまったく逆になっています。速度では優れた結果を出したdom4jが、メモリー使用量については、データ・バインディング・フレームワークよりもかなり悪い結果を出しました(ただし、JBindは例外です。JBindの場合は、dom4jのデータ表現に相当する内部文書モデルの上に対応関係を構築するので、もっとひどい結果になっています)。最高の結果を出したフレームワークに比べると、dom4jは同じデータ表現に10倍以上のメモリーを使っていることになります。

マッピング方式の2つのデータ・バインディングは、バインディング済みのデータの内部構造がいずれも同じなので、メモリー使用量の結果も同じになっています。この2つがメモリー使用量の分野でトップタイを分け合う形になっており、コード生成方式のデータ・バインディングよりも数倍のパフォーマンスを実現しています。その一因として挙げられるのは、マッピング方式のデータ・バインディングでは、データ値を非常にコンパクトに表現できるという点です。つまり、今回のテストでは、ほとんどのデータ値をint 値に変換しているわけです(たとえば、ほとんどのJava仮想マシン (JVM) では、String の場合は1~2文字で20バイト以上になるのに対し、int の場合は4バイトで済みます)。この変換のために読み書きに要する時間をロスしてしまうのは事実ですが、メリットは、メモリー使用量が少なくて済むことだけにとどまりません。実際にデータを処理する点でも、intString よりもはるかに便利で効率的だからです。

マッピング方式のデータ・バインディングがメモリー使用量の面で有利なのは、このようなプリミティブ値を幅広く使用できるからだけではありません。コード生成方式の場合は、バインディング済みのオブジェクトに存在する実際のデータに、制御情報が追加されてしまう場合がほとんどです。この制御情報がオブジェクトのサイズを膨らませ、データ・バインディングの大きなメリットの1つを失わせてしまうわけです。

コード生成方式のデータ・バインディング・フレームワークは、今回のテストでマッピング方式の少なくとも数倍のメモリーを消費していますが、それでも (JBindは例外として)dom4jの文書モデル表現よりははるかにメモリー使用量が少なくなっています。これは驚くような結果ではありません。dom4jなどの文書モデルは、文書のあらゆる構成部分を (つまり、実際のデータ・テキストのほかに、要素や属性などの構造用の部分も) 表現したオブジェクトを生成する必要があるのに対し、データ・バインディングでは実際のデータだけを保持しておけばよいからです。もちろん、コード生成方式の場合は、そのデータ値のかなりの部分をString として格納するわけですが、それでもint に変換できる値や、オブジェクト参照に変換できる値もある分、メモリー消費量が少なくて済むというわけです。

今回取り上げたデータ・バインディングの中で、Zeusだけは、すべてのデータをString として直接格納します。つまり、それだけ、メモリー消費量が多くなってしまうということです。ところが、JBindのメモリー消費量は、それよりもさらに飛び抜けて多くなっています。その一因は、文書モデルを内部で使用しているということですが、JBindのメモリー使用量は、dom4jなどの文書モデルが単独で必要とするメモリー量を数倍も上回っています。この結果から判断すれば、JBindは、バインディング設定と文書モデル内の実際のデータとを結び付ける数多くのオブジェクトを余計に生成しているのかもしれません。

初期実行速度

16 は、サーバー環境を想定してテストを何度も繰り返した上で、各種データ・バインディング・フレームワークのパフォーマンスをまとめたものですが、アプリケーションがデータ・バインディング・コードを利用して構成ファイルを読み書きするといった、いわば1回限りの実行環境でパフォーマンスがどう出るかというのも、たいへん興味のあるところではないかと思います。その結果をまとめたのが図7です。

図7. 初期実行速度 (単位はミリ秒)
図7. 初期実行速度 (単位はミリ秒)

7 が示している時間は、1つの小さな文書に関して、ベンチマーク・プログラムが起動してから、往復操作 (アンマーシャリングによってオブジェクトを生成し、マーシャリングによってそのオブジェクトを文書として書き戻す操作)が返ってくるまでの時間です。先ほどまでとは違い、今回はJVMがデータ・バインディング・フレームワーク・コードを処理するときの、クラス読み込みとネイティブ・コード生成に時間の大半が消費されています。今回の結果と先ほどまでの結果を比較すると、この初期実行にかかる時間は、かなり大きな文書の実際の処理にかかる時間のほぼ数倍になっているわけです。プログラムの1回の実行でごく少数の文書しか処理しない状況では、先ほどまでのテストで示した最高タイムの結果よりも、今回の初期実行速度の結果のほうがはるかに大きな意味を持ってきます。

この初期実行速度については、データ・バインディング・フレームワークが使用するjarファイル群のサイズが大きく影響します。このサイズが一番小さいのはJiBXで、実行環境とパーサーの分を合わせて60 KBもありません。一方、JAXB、Castor、JBindはかなり大きく、それぞれがほぼ1 MBになっています。また、この初期実行速度には、各フレームワークに必要な初期化の処理も影響します。マッピング方式のCastorの場合は、この初期化にマッピング定義ファイルの処理が含まれ、JBindの場合は文書のSchema定義の処理が含まれています。


JiBXって何物?

ここまでパフォーマンス結果を見てきたわけですが、ほとんどすべてのテストでトップになったフレームワークについて、少し説明を加えておく必要がありそうです。そのフレームワーク (つまりJiBX) は、言ってみれば替え玉のようなもので、実際にパフォーマンス重視の設計になっていることからして、その設計要件を満たしてさえいれば、パフォーマンス・テストでトップになるのは当たり前なのです。

実を言えば、このJiBXは今回の連載記事から生まれたフレームワークです。現在出回っているデータ・バインディング・フレームワークをいろいろ調べていて驚いたのは、dom4jなどの文書モデルに比べてあまりパフォーマンスが良くなかったということです。そんなはずはない、と私は思いました。そもそも、データ・バインディングの手法は、メモリー内に保持する文書情報が少なくて済むというところにメリットがあります。文書モデルはすべての情報を保持するのに対し、データ・バインディングでは実際のデータだけを保持すればよいからです。常識的に考えれば、処理するデータが少なければ、それだけ処理が高速になるはずではないでしょうか。

既存のデータ・バインディング・フレームワークの動作を調べているうちに、パフォーマンスの観点からして望ましくない要因が2つあることに気づきました。1つは、多くのフレームワークでリフレクションを多用しているということです。リフレクションとは、実行時にJavaクラスにアクセスするための1つの方法であり、ソース・コード内にクラス間のリンクが記述されていなくても、実行時に各クラスを動的に結び付け、クラス・インスタンス内のフィールドやメソッドにアクセスするというしかけです。このリフレクションはJavaテクノロジーの非常に強力な機能ですが、コンパイル済みのコードの中で直接的にメソッドを呼び出したり、直接的にフィールドにアクセスしたりする方法よりも、パフォーマンスが落ちるという欠点があります。

私が目を付けた2番目の要因は、文書のアンマーシャリングにSAX2パーサーを使っているという点です。SAX2はXML解析用の非常に便利な標準パーサーですが、そのイベント駆動型の手法は、データ・バインディングやこれと同類のアプリケーションにはあまり向いていません。要するに、SAX2のイベントを処理するコードは、すべての処理対象の状態情報を保持する必要があるため、処理が複雑になり、そこにパフォーマンス低下の原因が発生するというわけです。

そこで、既存のデータ・バインディング・フレームワークの2つの問題要因を回避して、Castorのマッピング方式を超えたさらに優れたマッピング方式を生み出したいとの思いから、そのあたりをテストするためのコードを書いているうちに、JiBXが出来上がったという次第です。JiBXでは、リフレクションの代わりにバイト・コード拡張機能を使って、プロジェクトのビルド時にアプリケーション・コードの中にフックを追加します。また、SAX2の代わりにプル・パーサー (現在はXMLPull) を使います。さらに、DTD記述やSchema記述からコードを生成する代わりに、ユーザー定義クラスとXML構造との対応関係を記述したバインディング定義を処理します。

これらのテクニックは、JiBX独自のものではありません。バイト・コード拡張機能は、多くのJDO (Java Data Objects) 実装でも使われており、その目的はJiBXの場合と基本的に同じです (つまり、既存のコンパイル済みコードにアクセス用のフックを追加するという目的です)。また、すでに廃棄された当初のJAXBコードは、XMLPullと同じようなプル・パーサー方式に基づいていました。さらに、マッピング方式のデータ・バインディングも、CastorとQuickがすでにサポートしています (ただし、制約がいくつかあります)。このように、個々のテクニックは決して新しいものではありませんが、その3つを組み合わせたところに、新たなデータ・バインディング・フレームワークとしてのおもしろさがあると思います。

JiBXについては、この連載の第3回で詳しく取り上げる予定です。もっとも、このJiBXはまだ開発の初期段階にあります。今回のパフォーマンス・テストのために、本来ならバイト・コード拡張機能によって追加するようなコードも手で書いていきましたし、そのコードを実行したJiBX実行環境もその当時のバージョンでした。この記事を書いている今も拡張機能コードを仕上げている最中ですし、追加してみたい機能の構想がいろいろあります。JiBXを詳しく取り上げる第3回の記事まで待てないという方は、参考文献で紹介しているJiBXサイトをご覧ください。フィードバックなどの形で今後のJiBXの開発を手助けしていただければうれしく思いますし、それぞれのアプリケーションで自由に活用していただいてかまいません。


結論

データ・バインディングに関する今回のパフォーマンス・テストでは、確かにおもしろい結果が出たとも言えますが、基本的には第1回の記事で書いた内容と大きく変わっていません。まず、Castorについて言えば、W3CのXML Schema定義からコードを生成する方式のデータ・バインディングに関する、現時点で最高のサポートが用意されています。アンマーシャリングのパフォーマンスは他のフレームワークよりも劣っていますが、メモリー使用量の面は優れており、初期実行速度もまずまずです。Castorの開発者たちによれば、1.0をリリースする前にパフォーマンスの問題点に取り組むということなので、その時点ではアンマーシャリングのパフォーマンスがいくらか改善されているかもしれません。

JAXBは、やはり将来的にコード生成方式の有力な選択肢になると思います(ベータ版のライセンスでは、評価のための使用しか認められていません)。現在の参考実装ベータ版では、jarのサイズが大きく、メモリーの使用効率があまりよくありませんが、パフォーマンスは今後改善されていくかもしれません。この記事を書いている時点でも最新バージョンは依然としてベータ版であり、正式版がリリースされれば、商用プロジェクトやオープン・ソース・プロジェクトが、参考実装よりも優れたパフォーマンスを実現する可能性もあります。JAXBはJ2EEプラットフォームに標準装備されることになるので、JavaによるXML処理という分野でこれから重要な役割を果たしていくのは間違いありません。

JBind、Quick、Zeusについては、汎用的なアプリケーションよりは特殊な要件を持ったアプリケーションに適していることが、今回のパフォーマンス・テストでも確認できました。まず、JBindの「XMLコード」という方式は、XML処理の周りにアプリケーションを構築するという発想の重要な基礎になりますが、現在の実装のパフォーマンスはやはり問題になる可能性があります。また、QuickとZeusは、コード生成に使用できるのがDTDだけになりますが、第1回の記事でも書いたように、DTDをSchemaに変換するのは基本的にごく簡単なので、その点は問題になりません。ただし、Quickは操作が非常に複雑だという欠点があり、Zeusはバインディング済みのデータ値としてString しかサポートしていないという欠点があります(つまり、プリミティブ値や、ID-IDREFを使ったオブジェクト参照などをサポートしていません)。

マッピング方式のデータ・バインディングについて言えば、Castorは、実装がかなり安定しており、実際の現場で広く使用されているという強みがあります。Quickもこの方式のデータ・バインディングに使用できますが、先ほども触れたとおり、セットアップが複雑なようです。その点、JiBXは新しく、まだ十分に使用されていませんが、パフォーマンスが優れ、柔軟性が高いのが特徴です。

第1回の記事をまだ読んでいない方は、これらのデータ・バインディング・フレームワークの機能について、ぜひ一読をお勧めしたいと思います。また、第1回では、データ・バインディングのコード生成方式とマッピング方式の比較についても触れています。では、次の第3回はどうなるかというと、今回取り上げた新しいJiBXフレームワークの詳細を説明したいと思っています。具体的には、JavaオブジェクトとXMLのマッピングの方法や、実行時のパフォーマンス低下を最小限に抑えるためのビルド時のバイト・コード拡張機能の処理などが、主なテーマになる予定です。パフォーマンスを改善するためのこの魅力的な方法の詳細については、次回の記事にどうぞご期待ください。

参考文献

  • データ・バインディングに関するこの連載の第1回では、XMLデータ・バインディングを使用する場合の条件や、データ・バインディング用の各種Javaフレームワークの概要が説明されています(developerWorks、2003年1月)。
  • この著者の以前の記事「Castorによるデータ・バインディング」をお読みください。Castorによるマッピング方式のデータ・バインディング技法を取り上げています (developerWorks、2002年4月)。
  • この著者による以前のdeveloperWorks 記事で、Java XML文書モデルの、performance(September 2001年9月)、およびusage (2002年2月) の比較を検討してください。
  • Brett McLaughlin氏のQuick関連記事 「QuickによるJavaオブジェクトとXMLの変換」をお読みください。Quickフレームワークを使って、Javaデータを簡単にXML文書に変換する方法を取り上げています。この場合は、他のデータ・バインディング・フレームワークとは違って、クラス生成セマンティクスは必要ありません(developerWorks、2002年8月)。
  • オブジェクト・リレーショナル・データ・バインディング(JDO規格と趣旨は同じものの互換性はない)の基本については、Bruce Snyder氏の「Castor JDOを始めよう」(developerWorks、2002年8月) をお読みください。
  • Javaオブジェクトの持続性を実現するためのJava Data Objects (JDO) APIの詳細をお読みください。
データ・バインディング・フレームワーク
  • Java Architecture for XML Binding (JAXB) の詳細をお調べください。これは、Javaプラットフォームのデータ・バインディングに関する新しい規格です。
  • Castor フレームワークの詳細をご覧ください。このフレームワークは、マッピング方式とコード生成方式の両方のデータ・バインディングをサポートしています。
  • JBind についてお読みください。このフレームワークは、Javaアプリケーションによって簡単にXMLを処理しようという発想ではなく、XMLの周りにアプリケーション・コードのフレームワークを作ろうという発想に基づいています。
  • Quick フレームワークの開発作業は、JavaプラットフォームやXMLよりも前にさかのぼります。これは、JavaプラットフォームでXMLを処理するための非常に柔軟なフレームワークです。
  • Zeus の詳細をご覧ください。Quickと同じように、XML文書のDTD記述に基づいてコードを生成しますが、Quickよりも操作が簡単で、機能が限られています。
  • マッピング方式のデータ・バインディングの新しいフレームワークであるJiBX の詳細をご覧ください。
他のリンク

コメント

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=XML
ArticleID=240099
ArticleTitle=JavaにおけるXML: データ・バインディング 第2回 パフォーマンス
publish-date=01012003