Datenorientiertes versus objektorientiertes Design

Videospiele sind gierig. Sie können eine enorme Menge an RAM und Rechenleistung erfordern und stellen im Allgemeinen eine enorme Belastung für die physische Hardware dar, die für das Abrufen, Bearbeiten und Zurückgeben von Daten verantwortlich ist. Aus diesem Grund ist eine Reihe von Befürwortern des datenorientierten Designs zu dem Schluss gekommen, dass das objektorientierte Design möglicherweise nicht die beste Methode ist, um den Code zu organisieren, mit dem diese monolithischen Anwendungen ausgeführt werden.

Was ist also datenorientiertes Design, wie unterscheidet es sich von OOP und welche Regeln gelten für das Schreiben von DOP-Code?

Wie unterscheidet es sich von OOP?

Wie der Name schon sagt, konzentriert sich die objektorientierte Programmierung auf das Definieren, Produzieren und Bearbeiten von Objekten. Es weist die Programmierer an:

  1. Stellen Sie fest, was Objekte sind.
  2. Bestimmen Sie, welche Datentypen zu einem Objekt gehören.
  3. Beschreiben Sie die Funktionalität eines Objekts.

Diese Objekte interagieren dann mit anderen Objekten über die Funktionen, die jedes Objekt besitzt.

Wie Objekte in OOP funktionieren

Einer der großen Vorteile von OOP ist, wie genau es zu spiegeln scheint, wie wir mit der realen Welt interagieren. Wenn ich zum Beispiel etwas über die Klasse der „Tabellen“ weiß, kann ich mir viel Zeit sparen, indem ich weiß, was ich mit einer Tabelle tun kann und was nicht. Sie würden niemals auf eine Instanz einer Tabelle verweisen und fragen, welche Art von Cappuccino diese Tabelle herstellt.

Aus diesem Konzept ziehen wir auch den Nutzen des Polymorphismus (Poly - Many; Morph - Forms), der ein Muster in der objektorientierten Programmierung beschreibt, bei dem Klassen unterschiedliche Funktionen haben und sich eine gemeinsame Schnittstelle teilen. Wenn Sie über die Klassifizierung von Tieren nachdenken und wissen, dass eine Katze und ein Tiger Teil der Klasse der „Katzen“ sind, weiß ich automatisch viel über sie, ohne auf die Besonderheiten ihrer jeweiligen Klassen einzugehen. Beide "erben" bestimmte Attribute und Daten von der höheren Klasse der Katzen.

Mit diesem Paradigma sind Funktionen jedoch auf bestimmte Daten beschränkt und können nicht wiederverwendet werden. Wenn Sie möchten, dass eine Funktion ein anderes Datenelement in einem Objekt verarbeitet, muss diese Funktion entweder von einer übergeordneten Klasse erben oder neu geschrieben werden. Es ist wichtig zu überlegen, wie in diesem Paradigma auf Daten zugegriffen wird, die in einer Klasse gespeichert sind, die von einer übergeordneten Klasse erbt. Die Daten müssen über mehrere Klassen abgerufen werden, um auf den Prozessor zugreifen zu können, was ineffizient sein kann.

Ein Beispiel für die Arbeit, die ein Prozessor in einem OOP-System ausführen muss.

Bei der datenorientierten Programmierung wird die Codierung etwas anders angegangen. Anstelle von Objekten ist alles Daten und alles kann bearbeitet werden. Dies trennt die Funktionalität und Daten. Sie sind nicht mehr durch einen bestimmten Regelsatz miteinander verflochten. In DOP dienen Ihre Funktionen allgemeinen Zwecken und werden auf große Datenmengen angewendet. Idealerweise strukturieren Sie die Daten so nah wie möglich an den Ausgabedaten, um sicherzustellen, dass die Funktion selbst den geringsten Aufwand verursacht.

"Datenorientiertes Design verschiebt die Perspektive der Programmierung von Objekten auf die Daten selbst: Die Art der Daten, wie sie im Speicher abgelegt sind und wie sie im Spiel gelesen und verarbeitet werden."
Ein Beispiel für eine DOP-Aufrufsequenz. Viel weniger Arbeit für den Prozessor.

Warum DOP?

Die einfache Antwort ist, weil Prozessoren die Referenzlokalität lieben. Diese Regeln bestimmen viele der anderen Vorteile, die uns mit DOP geboten werden. Wenn Sie beispielsweise Code schreiben, der für die Referenzlokalität optimiert ist, können Sie die Parallelisierung viel einfacher implementieren. Bei der Parallelisierung wird versucht, mehr als einen Kern des Computerprozessors zu verwenden, um Aufgaben gleichzeitig auszuführen. Dies kann mit OOP äußerst schwierig sein, da Sie das Risiko eingehen, dass mehrere Threads des Prozessors versuchen, gleichzeitig auf dieselben Daten zuzugreifen. Wenn Sie jedoch gleichgesinnte Daten gruppieren und Code schreiben, der sich auf die Daten konzentriert, die im Allgemeinen verarbeitet werden sollen, wird es viel einfacher, mehrere Threads des Prozessors für die Verarbeitung dieser Funktionen zu verwenden.

Ein weiterer Vorteil von DOP ist die effiziente Verwendung des Speichercaches. Da DOP immer wieder dieselben Funktionen verwendet, muss der Cache nicht immer neue, aber nicht wirklich neue Anweisungsblöcke speichern.

Quellen

https://www.danielsefton.com/2016/05/developing-a-data-oriented-game-engine-part-1/

https://www.packtpub.com/books/content/what-difference-between-functional-and-object-oriented-programming

https://www.gamasutra.com/view/news/126498/Opinion_What_You_Need_To_Give_Up_When_Going_Data_Oriented.php

https://prateekvjoshi.com/2013/11/30/programming-paradigms-object-oriented-vs-data-oriented/

http://gamesfromwithin.com/data-oriented-design