misc.log

日常茶飯事とお仕事と

設定ファイルがINI

.NET Framework1.1での新規開発で、過去の資産が等が無い状態でありながら、設定ファイルに「.ini」の従来形式を使うメリットって何だろう?

XMLにして、ドカっとデシリアライズで専用のオブジェクトに取り込んでしまうのが好みなんですが、誰もXMLという発想が無かったのかな??スピードか?

比べてみようか。

DevPartnerを使って時間計測。問題のコードは、ファイルの内容を読み込んで、HashTableに「Section|Key」という文字列をキーにして格納。設定ファイルは、19セクション、102行の文字データ。読み込んでHashTableに格納し終えるまでの時間、80,985.48マイクロセカンド...まてよ、中でConsole.Writelineとかやってる。読んだセクション名とかを書き出してるんだけど、これで、軽く20,000マイクロセカンドほど喰っちゃってる。コメントアウトして再計測。

61,664.61マイクロセカンド。やはりConlsole出力で時間喰ってるし...
で、デシリアライズ版を作るに当たって、XMLファイルと専用クラス作るのが大変なので、設定ファイルを1セクション、7キーに変更してみた。

さて、次はXMLとデシリアライズバージョン。これはこれから作るのでちょいまち。

できましたー。

方式 処理時間
INIファイル(Win32API) 19,659μs
XMLファイル(デシリアライズ 419,024μs

うひゃぁ。こりゃ遅い。ただ、実際に遅いのは、デシリアライズを行うXmlSerializerオブジェクトのNew。これで397,608μsも使っている。これさえなければ、実際の読み込みは約20,000μsとなるので大差なかったのだけど。

XmlSerializerをあらかじめ作っておいて、何度も読み書きするなら速度面はクリアできるかもしれないけど、XmlSerializerはコンストラクタで対象の型を指定するから、いろんなデータをやりとりするなら共用は難しい。単純に速度だけを見たら、Win32APIに軍配が上がるなぁ。でも、読み込んだモノを、セクション+キーという文字列で特定する方式で利用するとなると、読み手はセクション名とかを文字列として指定する必要があるということ。今回見てるソースは、そこを全部Constで定義しておいた文字列を指定するようになってるけど、そこが気色悪いよなぁ。

さて、次はXPathによる直接指定やってみようか。INIファイル側でやってる処理が、「セクション名の一覧を取得⇒各セクションごとにキーを有るだけ読み込む」という方式なので、同じような作りでやってみよう。

方式 処理時間
INIファイル(Win32API) 19,659μs
XMLファイル(デシリアライズ 419,024μs
XMLファイル(XPath指定) 80,625μs

XPath指定によるファイルアクセスも、一番遅いのは、XmlDocument.Loadメソッドでの初期読み込み。ここで51,064μs。あとは、各ノードを順に読んでいくのに、最初は約25,000μs、2つめは1,240μs、3つめは100μs...と、最終的には1件20μsくらいで読むようになる。キャッシュが生きているのかな? これもやはり、大規模なXMLドキュメントをガツンと開いて、必要なところをつまみ食い、というような用途ならいいんだろうけど、今の設定ファイルのアクセス方法を変えましょう、という提案には結びつきそうにない。

結局、iniファイル方式で処理ができちゃってるんだから、それでいけってことか。
厳密には、きちんと100件ほどのデータに対応した処理で計測しないといけないけど、少なくとも「XMLの方が早いです」とはならないであろうことは確実だし(そもそも早さを競うための表現方式じゃないしね)、まぁいいか。