Tout d'abord, ne confondez pas cela avec la conception basée sur les données.
Ma compréhension de la conception orientée données est qu'il s'agit d'organiser vos données pour un traitement efficace. Surtout en ce qui concerne les échecs de cache, etc. Data Driven Design d'autre part consiste à laisser les données contrôler une grande partie du comportement de vos programmes (très bien décrit par la réponse d'Andrew Keith ).
Supposons que votre application contienne des objets balle avec des propriétés telles que la couleur, le rayon, le rebond, la position, etc.
Approche orientée objet
En POO, vous décririez des balles comme ceci:
class Ball {
Point position;
Color color;
double radius;
void draw();
};
Et puis vous créeriez une collection de balles comme celle-ci:
vector<Ball> balls;
Approche orientée données
Dans la conception orientée données, cependant, vous êtes plus susceptible d'écrire le code comme ceci:
class Balls {
vector<Point> position;
vector<Color> color;
vector<double> radius;
void draw();
};
Comme vous pouvez le voir, il n'y a plus d'unité unique représentant une seule balle. Les objets Ball n'existent qu'implicitement.
Cela peut présenter de nombreux avantages en termes de performances. Habituellement, nous voulons effectuer des opérations sur plusieurs balles en même temps. Le matériel souhaite généralement que de gros blocs de mémoire continus fonctionnent efficacement.
Deuxièmement, vous pouvez effectuer des opérations qui n'affectent qu'une partie des propriétés d'une balle. Par exemple, si vous combinez les couleurs de toutes les boules de différentes manières, vous voulez que votre cache ne contienne que des informations de couleur. Cependant, lorsque toutes les propriétés de la balle sont stockées dans une seule unité, vous récupérez également toutes les autres propriétés d'une balle. Même si vous n'en avez pas besoin.
Exemple d'utilisation du cache
Disons que chaque boule occupe 64 octets et qu'un point prend 4 octets. Un emplacement de cache prend, disons, 64 octets également. Si je veux mettre à jour la position de 10 balles, je dois insérer 10 * 64 = 640 octets de mémoire dans le cache et obtenir 10 erreurs de cache. Si toutefois je peux travailler les positions des boules comme des unités séparées, cela ne prendra que 4 * 10 = 40 octets. Cela tient dans une extraction de cache. Ainsi, nous n'obtenons qu'un manque de cache pour mettre à jour les 10 balles. Ces nombres sont arbitraires - je suppose qu'un bloc de cache est plus grand.
Mais il illustre comment la disposition de la mémoire peut avoir un effet important sur les accès au cache et donc sur les performances. Cela ne fera qu'augmenter en importance à mesure que la différence entre la vitesse du processeur et de la RAM s'élargit.
Comment organiser la mémoire
Dans mon exemple de balle, j'ai beaucoup simplifié le problème, car généralement, pour toute application normale, vous aurez probablement accès à plusieurs variables ensemble. Par exemple, la position et le rayon seront probablement utilisés ensemble fréquemment. Alors votre structure devrait être:
class Body {
Point position;
double radius;
};
class Balls {
vector<Body> bodies;
vector<Color> color;
void draw();
};
La raison pour laquelle vous devriez faire cela est que si les données utilisées ensemble sont placées dans des baies séparées, il y a un risque qu'elles soient en concurrence pour les mêmes emplacements dans le cache. Ainsi charger l'un rejettera l'autre.
Donc, par rapport à la programmation orientée objet, les classes que vous finissez par créer ne sont pas liées aux entités de votre modèle mental du problème. Étant donné que les données sont regroupées en fonction de l'utilisation des données, vous n'aurez pas toujours de noms sensés à donner à vos classes dans la conception orientée données.
Relation avec les bases de données relationnelles
La réflexion sur la conception orientée données est très similaire à la façon dont vous pensez aux bases de données relationnelles. L'optimisation d'une base de données relationnelle peut également impliquer une utilisation plus efficace du cache, même si dans ce cas, le cache n'est pas du cache CPU mais des pages en mémoire. Un bon concepteur de base de données divisera probablement les données rarement consultées dans une table séparée plutôt que de créer une table avec un grand nombre de colonnes si seules quelques colonnes sont utilisées. Il peut également choisir de dénormaliser certaines des tables afin que les données ne soient pas accessibles à partir de plusieurs emplacements sur le disque. Tout comme avec la conception orientée données, ces choix sont faits en examinant quels sont les modèles d'accès aux données et où se trouve le goulot d'étranglement des performances.