SumatraPDF 開発者が std::function を放棄し、独自の16バイトコールバックソリューションを採用

BigGo 編集部
SumatraPDF 開発者が std::function を放棄し、独自の16バイトコールバックソリューションを採用

人気の Windows PDF ビューアである SumatraPDF の開発者が、C++ の標準ライブラリ関数から独自のコールバック実装への移行の経緯を共有した。16年間コードベースに取り組んだ後、彼らは std::function の使用の大部分を、高度な機能よりもシンプルさとデバッグ可能性を優先する独自のソリューションに置き換えた。

この決定は理論的な懸念ではなく、実用的なデバッグの課題から生まれた。本番環境でクラッシュが発生した際、ラムダ関数から自動生成される名前では、問題を特定のコード位置まで遡って追跡することがほぼ不可能になる。この現実世界でのデバッグの悪夢が、より明確なクラッシュレポートを提供する代替案を求める動機となった。

パフォーマンスとメモリの利点が独自実装を推進

独自のソリューションは、メモリ使用量とコンパイル速度の両方で具体的な改善をもたらしている。MSVC 64ビットシステムで std::function が64バイトを消費するのに対し、新しい Func0 と Func1 構造体はそれぞれ16バイトしか使用しない。この4分の1へのメモリフットプリント削減は、多くのコールバックを持つアプリケーションでは重要な意味を持つ。

実行時効率を超えて、この簡素化されたアプローチはコンパイル時間を劇的に短縮する。std::function の重いテンプレート性質は、コンパイラがすべての固有の型の組み合わせに対して新しいクラス定義を生成するため、実質的なコードの肥大化を生み出す。独自実装はこの複雑さを完全に回避している。

しかし、コミュニティは特定のパフォーマンストレードオフについて正当な懸念を提起している。独自ソリューションはユーザーデータにヒープ割り当てを必要とするが、std::function は小さなクロージャをインラインで格納することで最適化できる。これは、メモリの利点が常に明確ではなく、一部のシナリオではキャッシュの局所性が損なわれる可能性があることを意味する。

メモリ使用量の比較:

  • std::function: 64バイト( MSVC 64ビット)
  • カスタム Func0/Func1: それぞれ16バイト
  • メモリ削減: フットプリントが75%小さくなる

コミュニティがシンプルさと標準の間のトレードオフを議論

開発者コミュニティは、このアプローチが優れたエンジニアリング実践を表すかどうかについて意見が分かれている。批判者は、標準ライブラリソリューションを避けることで不要なメンテナンス負担が生まれ、コードの移植性が制限されると主張している。彼らは、std::bind や名前付き関数オブジェクトなどの代替案が、確立されたパターンを放棄することなくデバッグの懸念に対処できると指摘している。

支持者は、特に SumatraPDF の軽量で高速という評判を考慮すると、この実用的なアプローチを評価している。このアプリケーションの10MBというサイズは、典型的な現代ソフトウェアの肥大化とは対照的であり、すべての最適化がこの成果に貢献している。

「私のコード、私のルール、私の喜び。しかし哲学的に言えば、今日のほとんどのソフトウェアが即座に起動できず、ウィンドウを表示するために100MBものものを同梱している理由を疑問に思うなら、それはほとんどのプログラマーが物事を小さく高速に保つことに何の思考や努力も払っていないからです。」

この議論は、強力な標準ライブラリ機能を活用することと、個々の開発者が完全に理解し効果的にデバッグできるコードを維持することの間の、現代の C++ 開発における広範な緊張関係を浮き彫りにしている。独自ソリューションは柔軟性と一部の現代的な C++ の利便性を犠牲にするが、この特定のプロジェクトにとって最も重要な特定の要件を満たしている。

std::function との比較における トレードオフ:

  • 利点: メモリフットプリントの削減、コンパイル時間の短縮、クラッシュレポートの可読性向上、実装の簡素化
  • 欠点: 特定の関数シグネチャに限定、手動メモリ管理が必要、小規模関数最適化の欠如、より多くのボイラープレートコードが必要

結論

このケーススタディは、現実世界の制約が経験豊富な開発者を一見後ろ向きなソリューションに向かわせる可能性があることを実証している。SumatraPDF のアプローチはすべてのプロジェクトに適するわけではないが、機能の完全性よりもデバッグ可能性、コンパイル速度、メモリ効率を優先する開発者にとって貴重な洞察を提供している。コミュニティの反応は、普遍的に正しい答えは存在しないことを示している。最良のソリューションは、あなたの特定の要件と制約に完全に依存するのである。

参考: Simplest C++ callback, from SumatraPDF