Her şeyden önce, bunu veri odaklı tasarımla karıştırmayın.
Veri Odaklı Tasarım anlayışım, verilerinizin verimli işleme için organize edilmesiyle ilgilidir. Özellikle önbellek özledikleri vb. İle ilgili olarak Veriye Dayalı Tasarım, verilerin program davranışlarınızın çoğunu kontrol etmesine izin vermekle ilgilidir ( Andrew Keith'in cevabı tarafından çok iyi tanımlanmıştır ).
Uygulamanızda renk, yarıçap, kabarıklık, konum vb. Özelliklere sahip top nesneleriniz olduğunu varsayalım.
Nesneye Yönelik Yaklaşım
OOP'ta topları şöyle tarif edersiniz:
class Ball {
Point position;
Color color;
double radius;
void draw();
};
Ve sonra böyle bir top koleksiyonu yaratacaksınız:
vector<Ball> balls;
Veri Odaklı Yaklaşım
Bununla birlikte, Veri Odaklı Tasarım'da kodu şöyle yazmanız daha olasıdır:
class Balls {
vector<Point> position;
vector<Color> color;
vector<double> radius;
void draw();
};
Gördüğünüz gibi artık bir Topu temsil eden tek bir birim yok. Top nesneleri yalnızca örtük olarak bulunur.
Bu, akıllıca birçok avantajı olabilir. Genellikle aynı anda birçok top üzerinde işlem yapmak isteriz. Donanım genellikle büyük sürekli bellek parçalarının verimli çalışmasını ister.
İkinci olarak, top özelliklerinin sadece bir kısmını etkileyen işlemler yapabilirsiniz. Örneğin, tüm topların renklerini çeşitli şekillerde birleştirirseniz, önbelleğinizin yalnızca renk bilgisi içermesini istersiniz. Ancak, tüm top özellikleri bir ünitede saklandığında, bir topun diğer tüm özelliklerini de çekersiniz. Onlara ihtiyacınız olmasa bile.
Önbellek Kullanımı Örneği
Her topun 64 bayt, bir noktanın 4 bayt aldığını varsayalım. Bir önbellek yuvası da 64 bayt alır. 10 topun konumunu güncellemek istersem, 10 * 64 = 640 bayt belleği önbelleğe almam ve 10 önbellek özlemi almam gerekiyor. Ancak topların pozisyonlarını ayrı birimler olarak çalıştırabilirsem, bu sadece 4 * 10 = 40 bayt alacaktır. Bu bir önbellek getirme uyuyor. Böylece sadece 10 topu güncellemek için sadece 1 önbellek özledim olsun. Bu sayılar keyfi - önbellek bloğunun daha büyük olduğunu düşünüyorum.
Ancak bellek düzeninin önbellek isabetlerine ve dolayısıyla performansa nasıl ciddi bir etkisi olabileceğini gösterir. Bu sadece CPU ve RAM hızı arasındaki fark arttıkça önem kazanacaktır.
Bellek nasıl düzenlenir
Top örneğimde, sorunu çok basitleştirdim, çünkü genellikle herhangi bir normal uygulama için birden fazla değişkene birlikte erişeceksiniz. Örneğin, konum ve yarıçap muhtemelen sık sık birlikte kullanılacaktır. O zaman yapınız şöyle olmalıdır:
class Body {
Point position;
double radius;
};
class Balls {
vector<Body> bodies;
vector<Color> color;
void draw();
};
Bunu yapmanızın nedeni, birlikte kullanılan veriler ayrı dizilere yerleştirilirse, önbellekteki aynı yuvalar için rekabet etme riski vardır. Böylece birini yüklemek diğerini dışarı atacaktır.
Bu nedenle Nesne Odaklı programlamaya kıyasla, yaptığınız sınıflar sorunun zihinsel modelinizdeki varlıklarla ilgili değildir. Veriler, veri kullanımına bağlı olarak toplandığından, sınıflarınıza Veri Odaklı Tasarımda vermek için her zaman mantıklı adlarınız olmaz.
İlişkisel veritabanları ile ilişkisi
Veri Odaklı Tasarımın arkasındaki düşünce, ilişkisel veritabanları hakkındaki düşüncelerinize çok benzer. İlişkisel bir veritabanını optimize etmek de önbelleğin daha verimli kullanılmasını içerebilir, ancak bu durumda önbellek CPU önbelleği değil, bellekteki sayfalardır. İyi bir veritabanı tasarımcısı da çok az sütun içeren bir tablo oluşturmak yerine, nadiren erişilen verileri ayrı bir tabloya ayırır. Ayrıca, bazı tabloları denormalize etmeyi seçebilir, böylece verilere diskteki birden çok konumdan erişilmesi gerekmez. Veri Odaklı Tasarımda olduğu gibi, bu seçimler veri erişim kalıplarının ne olduğuna ve performans darboğazının nerede olduğuna bakarak yapılır.