Hacker News new | past | comments | ask | show | jobs | submit login

For those not familiar with this, here's a bit of background knowledge: A lot of game engines had run into an issue where a sensible and user friendly object oriented design led to a lot of little inefficiencies that added up to relatively poor performance. And fixing this became very tricky, since the problem manifested itself across multiple layers of code, and was a result of the access patterns that came with OO, in addition to poor cache optimization. In most applications this rarely matters (e.g. in a web-app the round-trips to the database will dwarf this), but in game engines you're trying to simulate and render a complex world 60 times per second, so you've got 16 ms for each frame, and you really don't want half of that being wasted on the CPU doing stuff that could have been avoided or not optimizing cache usage.

So an alternative to object-oriented design was proposed: Data oriented design - there's a good video about this from 2014 by Mike Ackton [1]. But in short, the idea is to go 'back to basics' and focus on this: You're pushing around and transforming bits of data so you can eventually give an output. So the goal of your design is to make it explicit how and when you do any of this, so you can avoid unnecessary copying, you can lay out data to fit efficiently in the cache, parallelize as much of this as possible, and do as little else as you possibly can. The result is the difference between opening Word and Sublime Text. In a web-context, Map-Reduce is a similar way of explicitly expression transformations in a way that enables parallelization.

A common pattern that many game engines have adopted as a result of this is Entity-Component-System [2]. Basically, most game engines work with a model where each object in the game world is an object with a list of components that give it varies attributes - e.g. a physics component to define how it handles collisions, a rendering component, a script component with some code to run every frame, etc. Previously that was also how it would be laid out in memory - an object contains the data from its components. With ECS this is inverted/exploded - the object is split up into an entity (basically just an id), each component's data is stored in an array along with all the components for other entities that also have that component (and the entity id is used to look up/associate in that array) and finally a system does transformations on the data in the component arrays. One of the benefits of this is that it lays out e.g. all the physics data continuously in memory, which makes it much easier to use the cache efficiently - for example if you load one components' worth of physics data into the cache, it might already include the next 1-3 chunks that just so happen to be exactly what the physics system will work on next. This blog post comes with some nice illustrations to help understand the difference between these two ways of laying out data [3]

[1] https://www.youtube.com/watch?v=rX0ItVEVjHc [2] https://en.wikipedia.org/wiki/Entity_component_system [3] https://medium.com/@savas/nomad-game-engine-part-4-3-aos-vs-...

Seems like there's a lot of similarities between DOD and relational modelling (as in modelling for a RDMBS). I imagine DOD is kinda like doing batch/bulk operations in pure SQL vs using an ORM.

It is almost exactly relational modeling. Instead of having an object that maps to an entity, you only have relations that hold information about various aspects of what you are modelling, and iterate over and join as needed.

Just adding a more recent video on it from CppCon 2018 where the presenter goes over a specific worked example.


Thanks for the clearly-written overview!

In some ways, this seems ~analogous to the web front-end world's adoption of unidirectional data flow and treating UI as a function of state.

25 years ago Word was renowned for its fast load time. Really! I don't use it now but I guess that's changed.

Thank you for your explanation!

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact