Home of: [工房 "藤車"] > [SourceForge.net における PageMixer]

直接描画

本節では、 最終的な描画における中間 String の生成コストの低減に関して説明します。

クラス名

本ドキュメントでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。

表記完全名
Token jp.ne.dti.lares.foozy.pagemixer.Token
Attribute jp.ne.dti.lares.foozy.pagemixer.Attribute
ConsumerContext jp.ne.dti.lares.foozy.pagemixer.mixer.ConsumerContext
Consumer jp.ne.dti.lares.foozy.pagemixer.mixer.Consumer
SafeWriter jp.ne.dti.lares.foozy.pagemixer.SafeWriter
MixingIOException jp.ne.dti.lares.foozy.pagemixer.MixingIOException

通常の設計

オブジェクトを文字列 (最終的にはバイト列へとなりますが)へと描画する方法として、 通常はオーバライドされた Object#toString() を利用します。

String の生成コストが思いの外高いため、 自身の描画に中間的な文字列(群)を必要とする設計は、 コストが高くついてしまいます。

例えば、 オブジェクトが階層構造をもっていて、 オブジェクト自身の描画内容を得るために、 配下のオブジェクトの描画内容が必要であると仮定します。 この時、処理手順は以下のようになります。

  1. 配下のオブジェクトの toString() を起動
  2. 配下のオブジェクトの toString() メソッドは、 結果の生成の為に、 いくつかの文字列要素を結合することも多々あるでしょう。

  3. 結果を繰り返し StringBuffer に格納
  4. 自身の描画を開始し、 結果を同じ StringBuffer に格納
  5. ここでも配下のオブジェクト同様に、 いくつかの要素を結合するかもしれません。

  6. 自身の toString() 戻り値として、 StringBuffer から String を生成
  7. 呼び出し側は、結果を java.io.Writer に対して書き出す

この場合、 対象およびその配下のオブジェクトが生成する toString() は中間文字列です。 単に最終的な描画結果の一部に過ぎないにも関わらず、 これらの文字列の生成(結合処理を含みます)コストは高くつきます。

PageMixer における判断

PageMixer では、 Token および Attribute の双方で、 render メソッドが定義されています。

描画の際には、 描画内容を構成する文字列を、 それらが描画先に直接書き出します。

この方法により、 中間文字列の生成コストを削減することが出来ます。 しかし、 render メソッドによる java.io.Writer への描画は、 Consumer クラスの consume(ConsumerContext, Token) メソッドおよび flush(ConsumerContext) メソッド起動の延長として行われるため、 これらのメソッドにおいて "java.io.IOException" 例外浮揚の宣言が必要となります。

少なくとも私にとっては、 Consumer 派生クラスの簡潔性を減少させるように見えますし、 "java.io.IOException" 例外の浮揚は、 Consumer 派生クラスより、 それらを利用する駆動クラスにのみ重要であるように見受けられます。

そこで PageMixer では、 java.io.IOException の補足/浮揚を省略するために、 render への描画先指定クラス SafeWriter と、 java.io.IOException の補足が必要なクラスはそれを補足できるように、 MixingIOException を定義しています。