経験に基づいた例を挙げましょう。私が日常的に使用するほとんどのライブラリは、何らかの形でOOPを使用しています。OOPは多くのドメインに必要な複雑さを隠すことができますが、パフォーマンスを実際に支援するメカニズムではありません。起こりうることは、ライブラリがオブジェクト階層に基づいて特定の最適化を使用できることですが、ほとんどの場合、複雑さをユーザーから隠すことです。デザインパターンを調べてください。これらは、この複雑さを隠すためによく使用されるメカニズムです。
例としてPETScを取り上げます。PETScは、OOPのインスペクター/エグゼキューターモデルを使用します。このモデルでは、アルゴリズムのいずれかが、特定のオブジェクトで使用可能なルーチンを調べ、ルーチンを達成するために実行するものを選択します。これにより、ユーザーは懸念事項を分離することができます。たとえば、マトリックスアクションには、あらゆる種類のブロックまたは最適化されたルーチンを含めることができ、多数の反復ソルバーで効果的に使用できます。ユーザーが独自のデータ型と評価を指定できるようにすることで、いくつかの重要なルーチンを高速化し、ライブラリ全体の機能を引き続き利用できるようにします。
もう1つの例として、FEniCSとdeal.IIがあります。これらのライブラリはどちらもOOPを使用して、多数の有限要素法を一般化します。要素の種類、要素の順序、直交表現など、すべてが交換可能です。これらのライブラリはどちらも、特定の目的の構造化FEMコードよりも「低速」ですが、FEMの複雑さの多くはユーザーに知られておらず、さまざまな問題を解決できます。
私の最後の例はElementalです。Elementalは、MPIコミュニケーターとデータの場所の管理の難しさを非常に単純な言語構造にした新しい高密度線形代数ライブラリです。その結果、FLAMEシリアルコードがある場合は、データ型を変更することで、Elementalを介してパラレルコードを使用することもできます。さらに興味深いのは、他の分布と同じ分布を設定することで、データ分布を試すことができることです。
OOPは、手作業のアセンブリと競合するためのパラダイムではなく、複雑さを管理する方法と考えるべきです。また、適切に行わないとオーバーヘッドが大きくなるため、タイミングを維持し、使用するメカニズムを更新する必要があります。