QMAIL3では、メール本文とは別にインデックスによく必要になる情報*1を保存しています。このインデックスは、固定長の比較的小さな情報(固定長インデックス)と、可変長の比較的大きな情報(可変長インデックス)に分けられていて、前者はフォルダごとに*.idxファイルに、後者はアカウントごとにindex.boxファイル(とindex.mapファイル)に保存されています。フォルダを開く(フォルダ内のいずれかのメッセージにアクセスする)ときには、そのフォルダの固定長インデックスがすべて読み込まれます。可変長インデックスはその時点では読み込まれず、メッセージごとに必要に応じて読み込まれます。
なので、フォルダを開いたときには、フォルダ内のメッセージ数が多くても極端に遅くなることなく開くことができます*2。
この、必要になるとき、というのはさまざまで、リストビューに描画するとき、マクロでアクセスされたときなどがあります。この中に、ソートするときやスレッド情報を生成するときも含まれます。日付やIDなどは固定長インデックスに含まれているのでそのままソートできますが、差出人や件名でソートしたときには可変長インデックスを読み込む必要がでてきます。
描画するときなどは、画面上に表示しているものだけ読み出しているのでそれほど遅くありませんが、ソートするときやスレッド情報を生成するときにはフォルダ内のすべてのメッセージの可変長インデックスを読み込むため、フォルダ内のメッセージが多くなるとそれなりに遅くなってしまいます。
そしてこの場合に、メッセージごとに必要になったタイミングで読み出していたため、結果的にかなりランダムにファイルにアクセスすることになり、バッファやキャッシュにヒットする確率が低くなってしまい、ますます遅くなっていました。というわけで、このような処理の前には、前もってファイル上で並んでいる順にソートしてからまとめて読み込むようにしてみました。
ディスクキャッシュにのっていないと思われる状態で、3万通ほど入ったフォルダで試してみると、スレッド情報を生成するのに10秒程度かかっていたのが、6,7秒程度に短縮されたのでそこそこ効果はあったようです。しかし、ディスクキャッシュに乗っている状態だと1秒程度で生成できてしまうので、なんだか無駄なことをしているような気も…
ところで、可変長のインデックスを一回読み込むと、そのメッセージを削除されたりしなければメモリ上にとどまり続けます。この最大値も一応qmail.xmlaccount.xmlのGlobal/IndexMaxSizeで指定できるようになっています。指定すると、メモリ上のインデックスが指定した数を超えたときに、もっともアクセスされていないものから順に破棄されていきます。
通常は指定する必要はないと思いますし、下手に指定すると極端に遅くなってしまいますが、以下の状況なら指定する価値があるかもしれません。
デフォルトだとフォルダXを開いたときに読み込まれたインデックスはQMAIL3を終了するまでメモリに残ってしまいますが、普段使っているフォルダに入っているメッセージの数+αくらいの数を指定しておくと、そのあたりのメモリが開放されて良いかもしません*3。
気持ち、早くなった気がしますね
やっぱりその程度ですよね。結局のところディスクキャッシュに乗るかどうかの方が支配的なので、内部のバッファにヒットするかどうかは、それに比べると影響が小さいようです。
最近 QMAIL3 を使っているノート PC の内蔵 2.5inchHDD を交換したんですが、4200rpm ⇒ 5400rpm、最大メディア転送レートが 245Mb/s ⇒ 493Mb/s になって、これは劇的に効きましたね