[AquaSKK] 辞書をなんとかしたいなぁ

ということで、2.4 をリリースしました。Safari/Camino で落ちにくくなっていると思いますので、「AquaSKK 使うとまともにブラウズできんっ! どういうことだっ!」と憤慨なさっていた方は、是非インストールしてみて下さい。今回はコンパイラの最適化オプションも見直しているので、辞書の読み込みなども若干早くなっていると思います。ただ、それでもやっぱり時間がかかるんですよね。

この、辞書の読み込みについてはずーっと気になっていたので、手元ではこっそり SKKDictionary の改善に向けた実験コードを書いてます。僕の開発マシンは iBook G4 1.2G なのですが、実験中のコードを使うと、L 辞書でも 1 秒そこそこでセットアップが完了します。これはちょっと驚きですよね。え、そんなことない?

まあ、タネを明かしてしまえば、std::map をやめて std::vector にしたり、CppCFString をやめて、std::string にしたりといった「手抜き」の積み重ねで実現した数字です。もちろんこのツケは漢字変換のタイミングで払わなければならないわけですが、それでも十分なパフォーマンスを確保できるんじゃないかと楽観してます。std::vector を使うことで、個人辞書の並び順を優先した補完も実現できそうだし、なんだか明るい兆しが見えてきました。

「でもさー、std::vector から見出し語を検索するのは、std::map よりも遅いんじゃないの?」なんて疑問を抱く C++ プログラマの方がいるかもしれませんね。僕もそう思っていました。そこで、L 辞書から見出し語の std::vector を作って検索するコードを書いてみたところ、わずか 0 秒(すなわち、計測不可能)で検索できました。

今の L 辞書は送りなしエントリが 157,859 個もありますが、これをソート済み std::vector にして、std::binary_search や std::lower_bound などのアルゴリズムを適用すれば、想像以上に高速に処理できます。いやー、STL って素晴らしい。ちなみに時間の計測は、手抜きをしてこんなクラスを使っています。

class StopWatch {
    const char* what_;
    clock_t begin_;

public:
    StopWatch(const char* what) : what_(what), begin_(std::clock()) {}
    ~StopWatch() {
	std::cerr << what_ << ": "
		  << (double)(std::clock() - begin_) / CLOCKS_PER_SEC
		  << " seconds." << std::endl;
    }
};