web-dev-qa-db-ja.com

データ指向設計とは何ですか?

私は この記事 を読んでいましたが、この男は、データ指向設計とOOPを混在させることで誰もがどのように大きな利益を得ることができるかについて話し続けています。ただし、彼はコードサンプルを表示しません。

私はこれをグーグルで調べましたが、コードサンプルはもちろん、これが何であるかについての本当の情報を見つけることができませんでした。この用語に精通している人はいますか?これは別の言葉かもしれませんか?

138
ryeguy

まず第一に、これをデータ駆動型設計と混同しないでください。

データ指向設計の私の理解は、効率的な処理のためにデータを整理することです。特にキャッシュミスなどに関しては、データドリブンデザインは、データがプログラムの動作の多くを制御できるようにすることです( アンドリューキースの答え で非常によく説明されています)。

アプリケーションに色、半径、弾力性、位置などのプロパティを持つボールオブジェクトがあるとします。

オブジェクト指向アプローチ

OOPでは、次のようにボールを説明します。

class Ball {
  Point  position;
  Color  color;
  double radius;

  void draw();
};

そして、次のようなボールのコレクションを作成します。

vector<Ball> balls;

データ指向アプローチ

ただし、データ指向設計では、次のようなコードを記述する可能性が高くなります。

class Balls {
  vector<Point>  position;
  vector<Color>  color;
  vector<double> radius;

  void draw();
};

ご覧のとおり、1つのボールを表す単一のユニットはもうありません。ボールオブジェクトは暗黙的にのみ存在します。

これには、パフォーマンスに関して多くの利点があります。通常、私たちは多くのボールを同時に操作したいと思います。ハードウェアは通常、メモリの大きな連続チャンクが効率的に動作することを望んでいます。

次に、ボールのプロパティの一部のみに影響する操作を行う場合があります。例えば。すべてのボールの色をさまざまな方法で組み合わせる場合、キャッシュに色情報のみを含める必要があります。ただし、すべてのボールプロパティが1つのユニットに保存されている場合は、ボールの他のすべてのプロパティも取得します。それらは必要ありませんが。

キャッシュの使用例

1つのボールが64バイトを占め、1つのポイントが4バイトを占めるとします。キャッシュスロットは、たとえば64バイトもかかります。 10個のボールの位置を更新する場合は、10 * 64 = 640バイトのメモリをキャッシュに取り込み、10回のキャッシュミスを取得する必要があります。ただし、ボールの位置を個別のユニットとして使用できる場合は、4 * 10 = 40バイトしかかかりません。 1回のキャッシュフェッチに収まります。したがって、10個すべてのボールを更新するためにキャッシュミスが1回しか発生しません。これらの数値は任意です。キャッシュブロックの方が大きいと思います。

ただし、メモリレイアウトがキャッシュヒットに重大な影響を与え、パフォーマンスに与える影響を示しています。これは、CPUとRAM速度の差が広がるにつれて重要性が増すだけです。

メモリのレイアウト方法

私のボールの例では、通常のアプリでは通常複数の変数に一緒にアクセスする可能性が高いため、問題を大幅に簡略化しました。例えば。位置と半径はおそらく一緒に頻繁に使用されます。次に、構造は次のようになります。

class Body {
  Point  position;
  double radius;
};

class Balls {
  vector<Body>  bodies;
  vector<Color>  color;

  void draw();
};

これを行う必要があるのは、一緒に使用されるデータが別々のアレイに配置されている場合、キャッシュ内の同じスロットをめぐって競合するリスクがあるためです。したがって、一方をロードすると他方がスローされます。

そのため、オブジェクト指向プログラミングと比較すると、作成するクラスは、問題のメンタルモデルのエンティティとは関係ありません。データはデータの使用量に基づいてまとめられるため、Data Oriented Designでクラスを指定するのに適切な名前が常にあるとは限りません。

リレーショナルデータベースとの関係

データ指向設計の背後にある考え方は、リレーショナルデータベースに関する考え方と非常によく似ています。リレーショナルデータベースの最適化には、キャッシュをより効率的に使用することも含まれますが、この場合、キャッシュはメモリにページを置くCPUキャッシュではありません。また、優れたデータベース設計者は、使用頻度の低いデータを別のテーブルに分割し、少数の列しか使用されていない膨大な数の列を持つテーブルを作成する可能性があります。また、ディスク上の複数の場所からデータにアクセスする必要がないように、いくつかのテーブルを非正規化することも選択できます。データ指向設計の場合と同様に、これらの選択は、データアクセスパターンが何であり、パフォーマンスのボトルネックがどこにあるかを見ることによって行われます。

257
Erik Engheim

Mike Actonは、最近、 データ指向設計 について公開講演を行いました。

私の基本的な概要は次のとおりです:パフォーマンスが必要な場合は、データフローについて考え、最も使いにくいストレージレイヤーを見つけて最適化しますhard。マイクはリアルタイムを行っているため、L2キャッシュミスに焦点を当てていますが、データベース(ディスク読み取り)やWeb(HTTP要求)にも同じことが当てはまると思います。システムプログラミングを行う便利な方法だと思います。

アルゴリズムと時間の複雑さについて考えることからあなたを免れず、気違いのCSスキルでターゲットにしなければならない最も高価な操作タイプを見つけることに注意を集中することに注意してください。

15

ノエルは、ゲーム開発で直面している特定のニーズについて具体的に話していることを指摘したいだけです。リアルタイムのソフトシミュレーションを行っている他のセクターはこれの恩恵を受けると思いますが、一般的なビジネスアプリケーションに顕著な改善を示す技術ではないでしょう。この設定は、パフォーマンスのすべての最後の部分が基礎となるハードウェアから絞り出されることを保証するためのものです。

12
bill c