Data-Oriented vs Object-Oriented Design

Jonathan Mines
4 min readMar 20, 2018

Video games are greedy. They can required a tremendous amount of RAM, processing power, and generally put a ton of strain on the physical hardware responsible for fetching, manipulating, and returning data. For that reason, a number of proponents of Data-Oriented Design have emerged to say that maybe Object-Oriented Design isn’t the best way of organizing the code that run these monolithic applications.

So what is Data-Oriented Design, how does it differ from OOP, and what are some of the rules surrounding how to think about writing DOP code?

How does it differ from OOP?

As it’s name suggests, Object-Oriented Programming is centered around defining, producing, and operating on objects. It directs coders to:

  1. Establish what objects are.
  2. Determine what types of data belong to an object.
  3. Describe the functionality an object has.

These objects then interact with other objects through the functions each object owns.

How objects work in OOP

One of the great benefits of OOP is how closely it seems to mirror how we interact with the real world. For example, by knowing something about the class of “Tables” I can save myself a lot of time by knowing what I can and cannot do with a table. You would never point to an instance of a table and ask “What kind of cappuccino’s does this table make?” because the class of tables does not give tables the functionality to make cappuccino’s.

Out of this concept we also get the benefit of Polymorphism (Poly — Many; Morph — Forms) describes a pattern in object oriented programming in which classes have different functionality while sharing a common interface. If you think about the classification of animals, by knowing that a cat and a tiger are part of the “feline” class, I automatically know a good deal about each of them without diving into any specifics of their particular classes. They both “inherit” certain attributes and data from the higher class of feline.

But, with this paradigm, functions are restricted to certain pieces of data and cannot be reused. If you want a function to operate on a different piece of data within an object, that function needs to either inherit from a parent class or needs to be rewritten. It’s important to think about how data held within a class that inherits from a parent class is accessed in this paradigm. The data needs to be fetched through multiple classes in order to be accessible the processor, which can be inefficient.

An example of the work a processor may have to do in an OOP system.

Data-Oriented Programming approaches coding in a slightly different way. Instead of objects, everything is data and everything can be acted upon. This separates the functionality and data. They no longer are intertwined by a specific rule set. In DOP your functions are general purpose and are applied to large chunks of data. Ideally, you would structure the data as closely to the output data as possible to ensure the least amount of effort is done by the function itself.

“Data-Oriented design shifts the perspective of programming from objects to the data itself: The type of the data, how it is laid out in memory, and how it will be read and processed in the game.”

An example of a DOP call sequence. Much less work for the processor.

Why DOP?

The simple answer is because processors love locality of reference. This rules dictates many of the other benefits given us with DOP. For example, writing code that optimizes for locality of reference gives us a much easier way to implement Parallelization. Parallelization attempts to use more than one core of the computers processor to execute tasks simultaneously. This can be extremely hard to do with OOP because you run the risk of multiple threads of the processor attempting to concurrently access the same data. However, when you group like-minded data together and write code focusing on the data that is going to be processed in general, it becomes much easier to use multiple threads of the processor to process those functions.

Another benefit of DOP is efficient use of memory cacheing. Because DOP utilizes the same functions over and over again, the cache isn’t forced to keep storing more and more new-but-not-really-new blocks of instruction.