データ指向設計(Data Oriented Design)とは何か
データ指向設計(DOD)は、コンピュータサイエンスとソフトウェアエンジニアリングにおける最適な設計アプローチです。このアプローチは、従来のオブジェクト指向設計(OOD)とは異なり、データの構造とアクセス方法に焦点を当てます。特に、ゲーム開発、シミュレーション、ハイパフォーマンスコンピューティングなど、リソースが制限されている環境で非常に効果的です。
データ指向設計の主要な原則は次のとおりです:
データの構造化: メモリアクセス速度を向上させ、キャッシュ効率を改善するために、データを構造化し、関連するデータを物理的に近い位置に保存します。
データの変換: プログラムをデータ変換の段階に分解し、各段階で必要な最小限の情報のみを使用してデータを処理します。
メモリアクセスの最適化: データを連続したメモリブロックに保存してキャッシュ局所性を向上させ、メモリアクセスを最小限に抑え、効率的にメモリにアクセスするアルゴリズムを使用します。
並列性の考慮: データを独立して処理できる小さな単位に分割し、並列処理を容易にし、マルチコアおよびマルチスレッドプロセッサのパフォーマンスを最大限に活用します。
データ指向設計の利点は、主にパフォーマンス最適化に関連しています。キャッシュ効率を向上させて演算速度を高速化し、並列処理によってマルチコアおよびマルチスレッドプロセッサのパフォーマンスを最大限に引き出すことができます。そのため、リソースが制限されている環境では、データ指向設計は好ましい設計アプローチとなっています。
シナリオで見る
「百万の商品の中から最も高い販売価格を取得してください」というシナリオで、コードを通じて説明してみましょう。
販売価格は価格(price)×数量(quantity)で構成されています。
オブジェクト指向設計に従うプログラミングは以下のようなものです。よく見かける形ですね。各Itemインスタンスを生成した後、他のオブジェクトを使用してGetterを介してメンバ変数の値を呼び出し、比較して返します。
// 1. 商品クラス
public class Item {
private String itemName;
private int price;
private int quantity;
private String description;
public Item(String itemName, int price, int quantity, String description) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
this.description = description;
}
public int getSellPrice() {
return this.price * this.quantity;
}
}
// 2. 百万の商品を格納
List<Item> items.add(... Itemのインスタンス)
// 3. 最大販売価格を取得
items.map((item) -> 最も高い販売価格を比較して返す
しかし、データ指向設計に従って作成すると、各商品の属性を順序通りに格納した後、一括でクエリする責任を持つメソッドを作成することになります。
// 0. 商品コレクションクラス
public class Items {
private static final int ONE_MILLION = 1000000;
private int currentIndex = 0;
// 商品の属性配列を順序(currentIndex)に合わせて格納する
private String[] itemName = new String[ONE_MILLION];
private int[] price = new int[ONE_MILLION];
private int[] quantity = new int[ONE_MILLION];
private String[] description = new String[ONE_MILLION];
// 商品を格納する関数
public void add(String name, int price, int quantity, String description) {
this.itemName[currentIndex] = name;
this.price[currentIndex] = price;
this.quantity[currentIndex] = quantity;
this.description[currentIndex] = description;
currentIndex++;
}
// 最大販売価格を返す関数
public int getMaxSellPrice() {
var maxPrice = 0;
for (int i = 0; i < this.currentIndex; i++) {
if(maxPrice <= this.price[i] * this.quantity[i]){
maxPrice = this.price[i] * this.quantity[i];
}
}
return maxPrice;
}
}
// 2. 百万の商品を格納
Items items = new Items();
items.add();
// 3. 最大販売価格を取得
items.getMaxSellPrice();
これらのコードを作成して比較してみると、オブジェクト指向コードに比べてデータ指向コードがより短い時間で動作することが確認できます。
なぜなら、ウェブ開発ではナノ秒単位の問題をあまり取り扱わないため、おそらくです。0.003秒の差はウェブ環境では大きな影響を与えないためです。そのため、パフォーマンスよりも可読性と保守性を重視する傾向があります。したがって、私たちは現在、オブジェクト指向設計をより多く使用していると考えられます。