Windows向けのPDFビューアとして始まり、現在は電子書籍やマンガの閲覧にも使えるマルチフォーマットビューアに進化した「SumatraPDF」の開発者であるクリストファー・コワルチック氏が、15周年を迎えたSumatraPDFを振り返りながらこれまでに学んだ教訓などをまとめています。
Lessons learned from 15 years of SumatraPDF, an open source Windows app
https://blog.kowalczyk.info/article/2f72237a4230410a888acbfce3dc0864/lessons-learned-from-15-years-of-sumatrapdf-an-open-source-windows-app.html
SumatraPDFはWindows向けのオープンソースビューアで、epubやmobiといった電子書籍向けのファイル形式から、PDFやDjVu、XPSなどさまざまなファイル形式のデータを閲覧することが可能です。コードは約12万7000行にもおよび、使用言語はC++を利用しているとのこと。コードはQtのようなGUI抽象化ライブラリを使用せず、Win32 API向けに書かれています。「これにより可能な限りコンパクトで高速動作可能なビューアを作ることができました」とコワルチック氏は語っています。
コワルチック氏は基本的にもうひとりのプログラミング仲間と共同でSumatraPDFの開発を行ってきたそうです。2007年から2022年までの15年間でどのくらいの時間(縦軸)を開発に費やしてきたかを簡易的にまとめたグラフを公開し、多くの時間を開発に費やしてきたとアピールしています。なお、SumatraPDFはあくまで趣味のプロジェクトであり、コワルチック氏は別に正規の職に就いているとのこと。
コワルチック氏はSumatraPDFを開発した理由を「2006年当時、私はPalmで働いていました。当時の仕事のひとつは、ARMとLinuxを搭載したミニノートPCであるFoleo用のPDFリーダーを作成することでした」「当時、私はPDFが一般的なデータフォーマットであることを知りませんでしたが、Palmの経営陣はPDFリーダーがFoleoには必須であると判断しました。そのため、私はFoleo向けPDFリーダーを開発するプロジェクトにおける唯一の開発者に任命されることとなったのです」と語っています。なお、Foleoは発売間近のタイミングでプロジェクトごとキャンセルされてしまい、製品化には至りませんでした。
PDFレンダリングライブラリの作成は数年にもおよぶ膨大な作業量を必要とします。しかし、コワルチック氏にはそのような膨大な時間がなかったため、オープンソースライブラリのPopplerを利用してPDFビューアを開発することにしたそうです。そのため、コワルチック氏は「Popplerを使ってPDFをメモリ内のビットマップにレンダリングし、そのビットマップを画面上に転送する基本的なPDFビューア」の作成に取り組むことになったと語っています。なお、PDFは複雑なファイル形式であるため、一部のPDFビューアはレンダリングが非常に遅いですが、ジェフ・ベゾスの「スピードは顧客が常に気にするものだ」という言葉が頭にあったというコワルチック氏は、「レンダリング速度を速くしたいと考え、開発に取り組んでいました」と語っています。
Foleo向けにPDFビューアを開発するところからスタートしたSumatraPDFの開発ですが、当時のARMハードウェア向けの開発ツールはあまり整備されていなかったそうです。そこで、コワルチック氏は「まともなプロファイラーがあったWindows向けにPopplerをコンパイルすることにしました」と語っています。PopplerがWindows上で動作するようになったら、ページを表示してページ間を移動できる最も単純なGUIアプリを作成。これをSumatraPDFのバージョン0.1としてホームページ上で公開したそうです。
あまりに簡素な機能だったためSumatraPDFのバージョンを0.1としたそうですが、すぐにプロダクトとしてリリースしたことで初期のユーザーをすぐに獲得することができ、ユーザーがどのような機能を求めているかを知ることができたとコワルチック氏。「何カ月も何年も苦労して多くの機能を実装するよりも、早くプロダクトをリリースすることは効果的でした。そもそもプロダクトの簡素さを誰も気にかけていませんでした」と記しています。
さらに、レンダリングに特に時間のかかったドキュメントをプロファイリングし、いくつかの驚くほどシンプルで効果的な最適化を実施することができたとコワルチック氏。同氏はコードのレビューを行わず、専任の品質保証チームもいない状態で、ほぼ単独で開発しながらコードの品質を高く維持したと記しており、そのために以下の方法を採用したとしています。
◆コードを自分でテストする
デバッガで新しく追加されたコードを操作し、新しく追加された機能が期待通りに動作することを確認する。
◆自動クラッシュレポート
自動のクラッシュレポートを作成するのは大変なものの、ソフトウェアの品質を向上させるためにできる最も重要なことであるとコワルチック氏。レポートをチェックすることで、コード変更の何が悪かったのかを考え、それを修正することが可能になります。
◆assert()
C++のコードでよく使われる手法であるassert()を利用して、デバッグビルド時にのみ実行される追加コードで、特定の条件が正しいことを検証するのも重要です。コワルチック氏はデバッグされていないプレリリース版ビルドでこれを有効にすることで、条件を満たした人から自動的にバグ報告を受け取ることができるようにしているそうです。コワルチック氏は「自分ひとりで必死にテストするよりも、1000人がアプリを使う方がはるかに多くのことを検証できます」と述べ、デバッグには多くの人が関わる方が良いとしています。
◆ログを取る
問題を調査する時、どのような一連の出来事がクラッシュにつながったかを知ることは助けになります。SumatraPDFのロギング・モジュールはメモリブロックにログを記録するようになっており、これはクラッシュレポートと一緒に送信されるようになっているそうです。ほとんどの場合、ログを気にすることはないそうですが、ログを有効にするためにアプリを再起動するのは面倒なため、ロギングアプリをSumatraPDFと分離することで、常にログを取得できるようにしているそうです。なお、ロギングアプリの実装は非常に簡単とのこと。
◆静的コード解析
Visual Studioの「/analyze」オプションや、Cppcheck、Clang-Tidy、GitHubの「CodeQL」といったツールを使い、エラーや警告を修正するのが効果的だそうです。
◆ASAN(Address Sanitizer)
Visual Studio 2019のいくつかのポイントリリースで追加されたASANは、非常に小さなパフォーマンスコストでメモリを上書きしたり、初期化されていないメモリを読もうとしたりすることができます。ASANを有効にしても「通常のビルドとして使用するのに十分な速度を保てる」とコワルチック氏。
◆ストレステスト
SumatraPDFは複雑なファイル形式のレンダリングがメインであるため、特定のファイルを開こうとする時にクラッシュすることがよくあるそうです。クラッシュがないことを保証するために、コワルチック氏はディレクトリ内のすべてのファイルを読み込んでレンダリングするストレステスト用のコードを作成したそうです。そして、このコードをリリース前のテスト時に使用しているとのこと。
◆ユニットテスト
文字列のフォーマットなど、低レベルの機能テストが主な用途で、あまり多くはないそうです。それでも「たまにバグを見つけることもあります」とコワルチック氏。
◆メモリリーク
使いやすいメモリリーク検出ツールを見つけるのは意外と難しいため、コワルチック氏は非常にシンプルなリーク検出ツールを自身で開発中とのこと。なお、このツールを開発している間、SumatraPDFではDr.Memoryを使用しているそうです。ただし、「動作はしますが、超遅いです」とコワルチック氏。
他にも、コワルチック氏は「少なくともひとつの注目すべき改善がある場合、新しいリリースバージョンとしてアップデートを行いました」と語っており、新しく書かれたコードの量に比例して頻繁にリリースを行うべきと主張しています。
さらに、オープンソースのプロジェクトを成功させたい場合は「商用ソフトウェアのようにプロダクトを扱うことが重要である」とコワルチック氏は記しました。具体的には、ソフトウェア用のウェブサイトを作成し、公開することが重要であるとしています。SumatraPDFもリリース初日からウェブサイトが準備されていたそうですが、このサイトを「6歳児が作ったウェブサイト」と揶揄(やゆ)する声もあったそうです。そのため、コワルチック氏は「嫌味な人やろくでなしを無視する」「つたないウェブサイトでもウェブサイトがないよりはまし」という2つの教訓を覚えておくべきと指摘。加えて、ウェブサイトで基本的なSEOを行い、ユーザーが質問したり機能リクエストを送ったりすることができるサポート用のフォーラムを用意することも効果的だったとしています。
さらに、ソフトウェアではシンプルさとカスタマイズ性が重要になるとコワルチック氏。シンプルさの重要性は、「Firefoxの歴史から学んだ」そうです。カスタマイズ性も重要ですが、設定ダイアログに100個の設定を並べるようなことは「適切な解決策ではない」とコワルチック氏。
この他、SumatraPDFがファイルサイズが小さくすぐに起動でき、高速動作できる点は「いまだに大きな利点になっている」とコワルチック氏は記しています。SumatraPDFを小さく保つため、コワルチック氏は不必要な抽象化を避けたとしています。特にWindows向けのソフトウェア開発は厄介で、「Qt、WxWindows、GTKなどさまざまなツールキットがあり、これらは非常に使いやすいものです。しかし、これらを利用するとファイルサイズはすぐに肥大化します」と述べ、利用を推奨していません。
また、オープンソースは良いビジネスモデルではないため、お金を稼ぎたいなら別の方法を模索するべきとしています。コワルチック氏はSumatraPDFのウェブサイトに広告を掲載するなどして収益を上げたそうですが、記事作成時点ではGoogle AdSenseの収益悪化によりほとんど収益を上げられなくなってしまったと打ち明けています。他にも、コワルチック氏はPatreonやPayPalで寄付を募っていますが、月の収入は100ドル(約1万4000円)以上ではあるものの「それ以上ではない」として、収益源としては不十分であるとしています。これらを踏まえ、「やりたいことを何でもできる自由さと、高給の両方を手に入れる機会はめったにありません。自分にとって重要なことは何かを選んでください。オープンソースは自由を提供しますが、お金は提供してくれません」とコワルチック氏は記しました。
この記事のタイトルとURLをコピーする