GNU sed 4.3登場 - 開発に携わって


GNUの開発に関わるようになったきっかけ

私がGNUの開発に関わるようになったきっかけは、2010年頃当時のGNU grepの最新版2.5.4が日本語環境で極端に遅かったことにあります。
コラムをご覧になられている皆さまも手元に開発ツールがインストールされたUnix/Linuxを用意できるようでしたら、実際にgrep 2.5.4をGNUのサイトからダウンロード、インストールして、動かしてみてください。以下の検索を行うと、結果が返されるまでにかなり時間かかると思います。

  $ gzip -cd grep-2.5.4.tar.gz | tar xf -
  $ cd grep-2.5.4
  $ ./configure
  $ make
  $ yes $(printf %040d 0) | head -10000 >inp
  $ time -p env LC_ALL=ja_JP.utf8 grep -v 0 inp

入力ファイルのサイズはたったの410KBです。以下のようにPOSIX(C)ロケール に切り替えて実行すると数ミリ秒程度で返されるため、明らかに異常なレベルの遅さです。

  $ time -p env LC_ALL=C grep -v 0 inp

私はこの結果にとても興味を持ちました。この遅さが日本語を扱うことの難しさから来るものなのか、はたまたGNU grepの不具合なのか。そしてそれを改善する方法はあるのか。そのような考えのもと、GNU grepのソースコードを解読していきました。その結果、マルチバイト環境においてのみ行われるキャッシュ処理において、その後に使用されない無駄なキャッシュが多数生成されることがあることを突き止めました。そこで、早速パッチ(修正コード)を作成してGNU grepプロジェクトに投稿しました。結局当時GNU grepのメンテナの1人だったPaolo Bonzini氏によりタッチの差で同様のパッチが投稿されたため、残念ながら私が書いたパッチは採用されるには至りませんでしたが、このようなことがきっかけでGNUのプロジェクトと関わりを持つようになりました。

その後しばらくは、GNU grepプロジェクトとの関わりは遠ざかっていましたが、2014年2月に大文字、小文字を区別しないマッチングで10倍の高速化したGNU grep 2.17がリリースされたというニュース(OSDN Magazineマイナビニュース)が私のもとに飛び込んできました。grepは非常に基本的なコマンドで、古くから開発、改良を続けられてきているため、すでに枯れ尽くしていて改良の余地はほぼ残されていない思われていました。ですから、このニュースを見た一部の人たちはとても驚きました。私も驚いた人の1人でした。

私はこのニュースを受けてGNU grepにはまだまだ改良の余地があると考えるようになり、GNUのプロジェクトとの関わりを深めていきました。

GNUへの貢献

私は主にGNU grepやGNU sedの性能改善やバグ修正のためのパッチを作成しプロジェクトに提供しています。
性能改善では、より効率的なアルゴリズムを実装して置き換えたり、無駄な処理を省いたりするパッチを作成しています。

バグ修正では、ユーザーやLinuxのディストリビューターによってプロジェクトに報告されたバグを実際に再現させ、修正するためのパッチを作成しています。また、修正されたことを確認するためのテストコードも作成しています。
マルチバイト対応部分のコードは、複雑ゆえに性能や品質があまり良くないことに加え、英語圏の開発者の多くはマルチバイトに明るくないため、私が特に力を入れている部分です。以前はマルチバイト環境では使いものにならないくらい性能が出ないケースも多くありましたが、最近のリリースではほとんどのパターンに対してシングルバイト環境で実行した場合と比べて遜色ないレベルになってきました。

ちなみに、プロジェクトへの貢献には他にもいくつかの形があります。

リリース前のテスト
GNUのプログラムは、Linux以外にもいろいろなCPUとOSの組み合わせをサポートしています。CPUはx86、x86-64、SPARC、Power、Itanium、PA-RISCなど、OSはLinux、Solaris、AIX、HP-UX、Windows (Cygwin, MinGW)などです。開発者が全ての環境を持ち合わせているわけではないため、マイナーな環境でコンパイルやテストを行い結果を投稿すると喜ばれます。
メッセージの翻訳
開発とは別のプロジェクトで進められ、リリース時にマージされます。GNU grep、GNU sedを含む多くのパッケージの翻訳はTranslation Projectで行われています。

他にも、ちまたで耳にしたバグの情報を提供したり、すでにプロジェクトで認識されているバグに対するテストコードを提供したり、こんな機能が欲しいとリクエストすることも立派な貢献です。

また、直接的ではありませんが、日本語の技術情報を公開したり、日本語コミュニティを立ち上げて普及活動を行うことも貢献と言えるでしょう。私が思いつくのはこのくらいですが、他にもいろいろな貢献の仕方があると思います。

もし、GNUの開発に携わってみたいと思われる方がいらっしゃいましたら、まずは、参加したいプロジェクトのメーリング・リストに参加してみてください。メーリング・リストに参加した時に自己紹介しなければならないなどの暗黙ルールなどはありませんし、退会したくなったらいつでも直ぐに退会することができます。

開発において苦労した点

これまでの開発において苦労した点を2つほど紹介します。これらは苦労したと同時にとても勉強になった点でもあります。

英語でのコミュニケーション
他の開発者とのやり取りは全て英文メールです。しかし、私はあまり英語は得意な方ではありません。そこで、読む方についてはインターネット上の辞書サイトを活用して必死で翻訳し、書く方については他の開発者が書いたものを真似たりすることで対応してきました。
また、パッチを投稿する際に書くコメントやコミット・ログはメンテナのJim Mering氏が丁寧に直してくれるため、とても勉強になっています。
日本語環境には存在しないルールの実装
GNUのプログラムは英語や日本語以外にも多くの言語をサポートしています。言語によっては日本語環境には存在しないルールが存在します。例えば、ギリシャ語環境ではΣ(シグマ)の小文字が2種類存在したり、トルコ語環境では大文字と小文字のバイト数が異なる文字が存在したり、スペイン語環境では照合シンボル (collating symbol) や等価クラス (equivalence class) と呼ばれるものが存在します。これらは日本語環境には存在しません。したがって、とても理解しづらく、実機でロケールを切り替えて試したとしても出力結果が文字化けしたりするためデバッグも大変です。
ロケールの規格は非常に複雑にもかかわらずドキュメント類はほとんどないため、GNU libc (glibc) のロケールに関するソースコードを必死で解読しました。

おわりに

このように、私はちょっとしたことがきっかけでOSSのプロジェクトと関わりを持つようになりました。その後、ソースコードの解読の範囲を広げていくことで貢献の範囲も広げてきました。そして、プログラミングやアルゴリズムに関するスキルだけでなく、グローバルの開発者たちとのコミュニケーション・スキルやOSSにおける開発/テスト方法などを身につけることができました。また、何よりGNU grepやGNU sedの仕様に詳しくなりました。

自分の書いたコードが世界中の人々に使用されることについてはとても責任を感じます。しかし、グローバルに対して貢献しているという大きな達成感があります。

このコラムを最後までお読みくださった皆さまがOSSの開発や貢献に少しでも興味を抱いていただければ幸いです。

(田中 紀洋)



GNU sed 4.3登場 - 開発に携わって