Introduction to Data-Oriented Design [pdf]

(gamedevs.org)

89 points | by tosh 5 hours ago

8 comments

  • dustbunny 4 hours ago
    The real key pillar to this world view is putting the data first in your design of the algorithm.

    So if your working on a physics engine and your optimizing collision detection, you think about the data in -> data out of the problem you are solving as the primary driver of how the code should be written.

    You start with defining the data, and build from there.

    Different types of applications all have different shapes of data so would have differently shaped optimal code. Eg) a physics engine would use some kind of spatial hash thing which can be optimized differently based on if stuff can be added/removed while it's running. A 3d renderer operates on big buffers of matrices and vertex data. A game is usually composed of some long lived things and a lot of short lived things.

    The key message in Mike Acton's talk was:

    "If you have different data, you have a different problem."

    While ECS systems are not a panacea that solves all problems in a perfect data oriented way, they are generally more malleable than Object Oriented hierarchies. This means it's generally more feasible to write "near optimal" code in an ECS framework than in a mature Object Oriented code base.

    But the key message isn't "use X framework", it's "start by defining the data".

    • inigyou 1 hour ago
      My experience with ECS is that you shouldn't use an "ECS system". You should just do ECS. Have an array of all your particles and then update all the positions according to the velocities. Don't use a framework where you do something like get_all_entities_with<Particle, Position, Velocity>(). Just have struct particles {vector<vec3> positions, velocities;}. Well, managing those parallel arrays gets pretty annoying, but you solve that with a parallel-array class template rather than a whole framework that promises to do everything. (You might not actually need parallel arrays anyway - AoS might work just fine here because you usually touch each field of each particle once per frame and exactly in order.)
      • slopinthebag 25 minutes ago
        The problem is that there are a lot of subtleties to an ECS that these frameworks solve, and they perform better than a naive approach too. Your solution of a particles struct doesn’t even support a fundamental feature of ECS’s which is runtime composition. It’s really a different solution altogether, which is fine but it’s not a replacement for an ECS.
        • inigyou 13 minutes ago
          Often you don't have runtime composition and don't need it. By prematurely generalizing you're venturing close to OOP territory.
    • wasmperson 51 minutes ago
      I feel like DoD is one of those things that only makes sense after you already believe in it. There's a sort of KISS epiphany that you have to go through which I don't think the commonly available info on DoD helps you to reach. It doesn't help that everything about it tends to get hung up on overly-specific C++ optimization advice.
  • HexDecOctBin 2 hours ago
    Mike Acton (author of this presentation) has released a LLM skill for Data Oriented Programming: https://github.com/macton/nagent/blob/main/context/data-orie...
    • zx8080 19 minutes ago
      > You are working for Mike Acton.

      AI generated skill?

  • ghosty141 2 hours ago
    I personally love the idea of DoD but from my experience it rarely works well in practice since one of the key assumptions of understanding ur problem is often not given as new requirements pop up and change all the time.

    At work we are rewriting and reengineering system from scratch and its crazy because the limitations of the old system are now gone we get the most insane feature requests that are even accepted by the team lead et al. This makes such an approach impossible since DoD is exactly the opposite of flexible design in my opinion.

    Im curious has anybody really followed this in a big long living commercial project?

    • shoo 1 hour ago
      DoD may be a good idea for a business context where one of your main priorities is getting the most efficient use out of memory bandwidth & cache.

      E.g. if your job is writing game engines or middleware used by AAA games with fancy graphics to run on consumer hardware, getting the most efficient use out of the players' limited memory bandwidth may be very important.

      For many (most?) arbitrary commercial software projects in other contexts, performance isn't high priority & memory bandwidth isn't a bottleneck. Performance just has to be 'good enough' & 'good enough' performance may be easily attained by writing typical OO code that uses cache & memory very inefficiently - so in those cases DoD is an engineering trade off that solves a problem that doesn't need to be solved & may create new problems if introduced.

    • hecreto 2 hours ago
      Based on your description the only prescriptive thing one can say is lean into composition and avoid inheritance. While there are some pitfalls with composition it is easier to unpack and restructure than inheritance is. Changing requirements will of course incur changing data structures etc. but hopefully this can be avoided a bit by using LUT/indexes and other things to minimize impact.
    • ButlerianJihad 49 minutes ago
      Why do you lowercase "oriented" when "DOD" (and "OOD") is the usage in the slides?
  • slopinthebag 14 minutes ago
    I wish people weren’t so dogmatic about DOD. It’s applicable mainly when you have extremely large amounts of data which can be processed in parallel, which seems mostly the case with video games (eg. look at most DOD examples) and other niche cases. It’s called “Data-Oriented Design” but it really should be called “parallel-processing design” because the average DOD advocate will never advocate for a different OOP approach if it solves a problem where those techniques are more appropriate. Advocates tend to be quite dogmatic, ask them about RAII or modern C++\Rust for example and you’ll see what I mean.

    And I say this as someone who basically sees programming as data and associated algorithms and always approaches problems by considering state or data first.

  • PessimalDecimal 2 hours ago
    This seems like a particular branding on cache-aware data structures and algorithms. Is there more to it?
    • wasmperson 23 minutes ago
      One good example of DoD which isn't CPU-cache-related is relational databases. When designing a CRUD application, the Data-Oriented way of doing it is to figure out what data you will be storing and how to organize that data to minimize access times, which is what you're doing when you design the DB schema.

      An example of failing to follow DoD is the N+1 query problem: a programmer builds an abstraction that operates on individual DB rows, but "where there's one, there's more than one": you will inevitably be running that code in a loop so that you can process multiple rows. If instead the programmer had abstracted over groups of rows, then per-item query overheads suddenly become per-batch overheads.

    • inigyou 1 hour ago
      I consider it generally the ideology of anti-OOP. While OOP ideology teaches you to structure the program after the problem it solves, DOD ideology explicitly teaches you to throw all that away and think about what runs fastest on the computer. Maybe it should be called Computer-Oriented Programming or Hardware-Oriented Programming. The specifics very a lot but the top-level ideology of "fuck OOP" is consistent.

      People posted a wide variety of specific ideas under my other comment: https://news.ycombinator.com/item?id=49061421

  • inigyou 4 hours ago
    Serious question. Does DOD mean anything more than array programming, in practice?
    • laladrik 4 hours ago
      Have a look at the talk Practical Data-Oriented Design by Andrew Kelly [1]. He covers the following techniques:

      1. Indexes instead of pointers. This allows you to avoid alignment of 8 bytes in your structure for x86_64.

      2. Storing booleans out-of-band. Booleans cause padding all the time.

      3. Struct of Arrays. Based on your question I assume you're familiar with it.

      4. Store sparse data in hash maps. I remember one time when it allowed to eliminate inheritance.

      5. Encoding the data instead of OOP/polymorphism. I haven't got an occasion to use it. The idea is to add extra tags to avoid boolean properties.

      [1] - https://vimeo.com/649009599

    • lioeters 3 hours ago
      - Data-Oriented Design Revisited: Type Safety in the Zig Compiler - Matthew Lugg - https://youtu.be/KOZcJwGdQok?si=YDal2Gwb0IJPFgrI

      - Andrew Kelley Practical Data Oriented Design (DoD) - https://youtu.be/IroPQ150F6c?si=F1Z0pLO2W5hbQgpM

      - CppCon 2014: Mike Acton "Data-Oriented Design and C++" - https://youtu.be/rX0ItVEVjHc?si=jv4hhTSBh3XH--xQ

      - Why You Shouldn’t Forget to Optimize the Data Layout - https://cedardb.com/blog/optimizing_data_layouts/

      - Handles are the better pointers - https://floooh.github.io/2018/06/17/handles-vs-pointers.html

      - Enum of Arrays - https://tigerbeetle.com/blog/2024-12-19-enum-of-arrays/

      - Data oriented design book - https://www.dataorienteddesign.com/dodbook/

      - Data-oriented design in practice - Stoyan Nikolov - https://youtu.be/_N5-JjogNXU?si=vhaxYcfE6tl11Sux

      - Programming without Pointers - Andrew Kelley - https://www.hytradboi.com/2025/05c72e39-c07e-41bc-ac40-85e83...

      - More Speed & Simplicity: Practical Data-Oriented Design in C++ - Vittorio Romeo - CppCon 2025 - https://youtu.be/SzjJfKHygaQ?si=jafavSl2YJWk4vIx

      - Rust Handle - https://taintedcoders.com/rust/handles

    • sirwhinesalot 3 hours ago
      Yes. Array programming happens to overlap heavily with DOD in modern hardware because of caching and SIMD, but if you were programming an Atari ST it wouldn't.

      There are also cases where the optimal data format isn't array oriented because the memory access patterns for the problem in question just require something else.

      You also have to think of hot vs cold data, which has nothing to do with arrays.

    • jordand 4 hours ago
      A lot of it just comes down to KISS and avoiding unnecessary overhead and indirection (like vtables, C++ STL containers etc.) so you're getting the most out of the hardware.
      • laladrik 3 hours ago
        It's fair to mention that DOD is not only getting the most out of the hardware. It also allows the busy work to be avoided. I caught myself a couple of times, when I wanted to make a set of types united by some interface. However, in reality what I could do (and I did eventually) is having several instances of single SOA (one per type) which were processed differently. The addition of a new "type" turned from a good hundred line patch to 20-30 lines
    • atoav 3 hours ago
      It means instead of building a street object, with car objects that have tire objects as its children and then running through the tree to rotate the wheels you just have an array pointing to exactly the appropriate data type to accomodate the type of wheel rotation you need.

      Very often the answer is indeed arrays, but it can easily be something else, depending on the problem. Data driven design is not very complicated, it just means instead of thinking about abstraction you think about the shape the data needs to be in to accommodate the most common transformations you need to do with it.

    • RobRivera 4 hours ago
      Yes
  • Veliladon 37 minutes ago
    [dead]
  • Ernestafaton 2 hours ago
    I find this information very useful; thank you.