5 ms·
Introduction to Data-Oriented Design [pdf]
- inigyou 3mo agoSerious question. Does DOD mean anything more than array programming, in practice?
- RobRivera 3mo agoYes
- laladrik 3mo agoHave 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 https://vimeo.com/649009599
- jordand 3mo agoA 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 3mo agoIt'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
- sirwhinesalot 3mo agoYes. 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.
- inigyou 3mo agoCan I propose renaming it to Hardware Oriented Programming?
- corysama 3mo agoThat would be https://martinfowler.com/articles/mechanical-sympathy-principles.html https://martinfowler.com/articles/mechanical-sympathy-princi...
- sirwhinesalot 3mo agoEh, I don't think that's a good renaming. Data-Oriented Design is in opposition to Domain-Driven Design (a software development approach that prioritizes modeling software to match a real-world business domain). OOP tells you to structure your software as objects exchanging messages, and DDD tells you what those objects (or their classes rather) should be. Similarly, Procedural programming tells you to structure your software as procedures, and DOD tells you what those procedures should operate on. The focus on the data is the really important part. What is the actual data I'm operating on (without any fluff on top) and what do I need to transform it into? What subsets of that data need to be operated on at any given point in the program? That's the core of DOD. Then, as a second step, comes the hardware. Now that I know what data I need to operate on, how do I lay it out to best take advantage of the hardware I'm targeting? If you rename the paradigm to "Hardware Oriented Programming", it shifts the focus from data modeling to code (IMO), which is the wrong frame of mind. For example, virtual calls are slow compared to direct calls, because they screw up branch prediction and often can't be inlined. In HOP, you'd probably ban virtual calls entirely because virtual calls bad. But in DOD, they honestly probably don't matter at all! Because if you did the data modeling as instructed, and then you laid out the data to best take advantage of the hardware, your virtual function is going to be operating on a pile of data in bulk, making the virtual call cost pure noise.
- atoav 3mo agoIt 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.
- lioeters 3mo ago- Data-Oriented Design Revisited: Type Safety in the Zig Compiler - Matthew Lugg - https://youtu.be/KOZcJwGdQok?si=YDal2Gwb0IJPFgrI https://youtu.be/KOZcJwGdQok?si=YDal2Gwb0IJPFgrI - Andrew Kelley Practical Data Oriented Design (DoD) - https://youtu.be/IroPQ150F6c?si=F1Z0pLO2W5hbQgpM https://youtu.be/IroPQ150F6c?si=F1Z0pLO2W5hbQgpM - CppCon 2014: Mike Acton "Data-Oriented Design and C++" - https://youtu.be/rX0ItVEVjHc?si=jv4hhTSBh3XH--xQ https://youtu.be/rX0ItVEVjHc?si=jv4hhTSBh3XH--xQ - Why You Shouldn’t Forget to Optimize the Data Layout - https://cedardb.com/blog/optimizing_data_layouts/ https://cedardb.com/blog/optimizing_data_layouts/ - Handles are the better pointers - https://floooh.github.io/2018/06/17/handles-vs-pointers.html https://floooh.github.io/2018/06/17/handles-vs-pointers.html - Enum of Arrays - https://tigerbeetle.com/blog/2024-12-19-enum-of-arrays/ https://tigerbeetle.com/blog/2024-12-19-enum-of-arrays/ - Data oriented design book - https://www.dataorienteddesign.com/dodbook/ https://www.dataorienteddesign.com/dodbook/ - Data-oriented design in practice - Stoyan Nikolov - https://youtu.be/_N5-JjogNXU?si=vhaxYcfE6tl11Sux https://youtu.be/_N5-JjogNXU?si=vhaxYcfE6tl11Sux - Programming without Pointers - Andrew Kelley - https://www.hytradboi.com/2025/05c72e39-c07e-41bc-ac40-85e8308f2917-programming-without-pointers 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 https://youtu.be/SzjJfKHygaQ?si=jafavSl2YJWk4vIx - Rust Handle - https://taintedcoders.com/rust/handles https://taintedcoders.com/rust/handles
- dustbunny 3mo agoThe 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 3mo agoMy 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 3mo agoThe 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.
- HexDecOctBin 3mo agoMike Acton (author of this presentation) has released a LLM skill for Data Oriented Programming: https://github.com/macton/nagent/blob/main/context/data-oriented-design.md https://github.com/macton/nagent/blob/main/context/data-orie...
- zx8080 3mo ago> You are working for Mike Acton. AI generated skill?
- QuantumNomad_ 3mo agoPossible, but regardless of whether or not that is the case his name is well known enough and he has been around long enough that his name definitely appears in a lot of the texts the LLMs were trained on, in contexts that relate to his views on programming. Try asking your LLM of choice this in an empty session with no other context: You are working for Mike Acton. What principles do you follow when writing code? Maybe he found that telling it that it works for him nudges it in a direction that is beneficial to get it to write code like he wants, alongside the specific rules and other instructions in the above linked document?
- parpfish 3mo ago> Maybe he found that telling it that it works for him nudges it in a direction that is beneficial I think that’s call “spooky Acton at a distance”
- saghm 3mo agoI started writing up a giant response to this about how all of LLMs are spooky action at a distance but for better or for worse, that doesn't make them any less useful, and a few paragraphs in I suddenly noticed what you actually wrote. Well played :)
- Ernestafaton 3mo agoI find this information very useful; thank you.
- PessimalDecimal 3mo agoThis seems like a particular branding on cache-aware data structures and algorithms. Is there more to it?
- inigyou 3mo agoI 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 https://news.ycombinator.com/item?id=49061421
- groundzeros2015 3mo ago> While OOP ideology teaches you to structure the program after the problem it solves I completely disagree with this characterization. OOP teaches you a synthetic set of concepts (go4) and then asks you to solve problems in terms of that. And the reason why the canonical bird as a subclass of animal doesn’t work, is it’s extremely difficult to divide the world into strict categories (are you Aristotle). So the solution is to organize virtually rather than around natural traits. The most natural way to solve a programming problem is a big list of instructions with if/else and goto. It’s very learnable, even for young children.
- inigyou 3mo agoOOP is not Singleton, it is "class Car extends Vehicle {Tyre tyres[4]}" etc
- groundzeros2015 3mo agoI responded to that. It’s nonsense which doesn’t work: > And the reason why the canonical bird as a subclass of animal doesn’t work, is it’s extremely difficult to divide the world into strict categories (are you Aristotle) What behavior are you going to out in vehicle? Here are a few potential subclasses you’ll need to consider: - hang glider - wheelies - train - skis - lawn mower - windsurfing board
- ghosty141 3mo agoI 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?
- hecreto 3mo agoBased 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.
- shoo 3mo agoDoD 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.
- FpUser 3mo agoI have business oriented C++ backend where I use mostly OOP but also use DoD in few critical places that do a lot of calculations over big chunks of data. It is simpler than for games since I only need high average performance, not real time 60 or whatever FPS with no jitter.
- Veliladon 3mo ago[dead]
- slopinthebag 3mo agoI 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.
- Quothling 3mo agoI knew OOP had failed when we started getting programmers who solved memory issues with batching instead of thinking about why they were loading that much data into the memory to begin with. For the previous 20-30 years that didn't really matter. Code was the bottleneck and implicity and abstractions helped developers ship changes faster. It turned out that it didn't give us maintainable or safe code bases, and there is a sweet irony to be found in the world of banking. Where the JAVA systems meant to replace the old parallel paradigms are now being replaced with systems that are better links between the COBOL systems and the customers than JAVA ever was. AI changes that. Especially because it appears that LLM's can't understand the OOP abstractions any better than your hardware can compute it. That being said. OOP and DOD both have advantages and disadvantages. If you go back to what I said first it wasn't exactly a failing of the OOP paradigm. The biggest issue I have with OOP is actually that it's too easy to do things wrong with it. Which isn't helped by the multimillion dollar industry which thrives on teaching developers everything except core computer science. People know their DRY, SOLID, CLEAN, TDD, Agile and every design pattern in the world, but they don't know how the interface they've just implemented actually handles their data.
- crabmusket 3mo agoI think this is broadly true, but there's also a subset of DOD design advice (e.g. see Richard Fabian's book) that has a lot to say about relational database design. In our team it's provided us with some very practical motivation for more normalised table designs. Doing 1+n requests to the database due to poor implementation feels similar now to pointer chasing. The connection is that ORMs convince you to have an object-oriented view of the world, which maps nicely to object classes. But highly normalised designs don't map as cleanly to classes and objects, so you need to approach with a different style of programming on the application side. Instead of seeing a User instance, you start to see a more complex bundle of login methods, profile events, etc.
- asdaqopqkq 3mo agocan we train more LLMs on this and also the codebase of handmade hero?
- remiminnebo 3mo agoThat's where my agents got it from!
- ChicagoDave 3mo agoDomains should own their data and some data objects can be split between domains. Data first is fine for simple systems, but lead to chaos for complex systems.
- thomascountz 3mo agoI'm surprised not to see Odin[1] mentioned. DoD is one of its central paradigms. [1]: https://odin-lang.org/ https://odin-lang.org/
- deepnlp-contact 3mo ago[dead]
- andreygrehov 3mo agoI would strongly recommend reading Data-Oriented Programming in Java by Chris Kiehl [1]. Chris introduces you to the data-oriented thinking through a series of super basic examples, gradually making things more interesting. He leverages the latest Java features (e.g. record classes) to illustrate the ideas and explains why these features are important. I don't know him personally, but we both work at AWS. I liked the book so much, that I reached out internally thanking him for writing the book. [1] https://www.manning.com/books/data-oriented-programming-in-java https://www.manning.com/books/data-oriented-programming-in-j...
- btschaegg 3mo agoNote: AFAIU "Data Oriented Programming" (as championed e.g. in the Clojure community) and "Data Oriented Design" (as championed in the video game community) are very different philosophies for different use-cases and diametrically opposed on many dimensions. People knowing only the one phrase and assuming both to be synonymous will be in for a lot of confusion when reading about the other.
- andreygrehov 3mo agoAh, thanks for flagging. You are 100% correct.
- g9550684 3mo agothese are obvious techniques from array world, j/k/apl, and the source of e.g. arthur's bold speed claims. personally I've discovered it insufficient to "just" convert tables to lists, you also need to understand the rest of the array principles to then effectively manipulate your data, and just to be able to hold compute in your head. because I believe in this approach I spent time learning j and k, but the end result is that my solutions become too alien for the general practitioner. it becomes apl written in whatever host language. this is something that is not addressed in a lot of DOD talks, what happens when you do the full realization of technique: bulk list primitives, bulk transforms, SIMD optimizations, list compression, etc. and it's also the reason people claim this only works in narrow scopes (like gamedev). in reality you can write all your code for lack of better term the apl way, you're just going to make it unreadable to non apl practitioners. I'm not quite sure how to reconcile this in general, short of forcing apl to be part of general CS curriculum.
- g9550684 3mo ago> convert tables to lists array languages give you concepts for thinking about these problems where you can succinctly express that entire talk in a single sentence, something like "inverted tables improve cache locality and optimize for time and space, prefer them where it matters". yes, got it, also a well known conclusion in array world. a table is a 2 dimensional data that stores your records row by row and the items of a column all have the same data type. the way an array of structs would. an inverted table is a list of original table's columns. like a struct of arrays. so if you have a table, x ┌────┬──────┬─┬─────────┐ │mob1│level1│0│0.0243902│ ├────┼──────┼─┼─────────┤ │mob2│level2│1│0.0147059│ ├────┼──────┼─┼─────────┤ │mob3│level2│0│0.0120482│ └────┴──────┴─┴─────────┘ there's an idiom for converting it to an inverted table ]y=:(<@(>"1)@|:)x ┌────┬──────┬─────┬─────────────────────────────┐ │mob1│level1│0 1 0│0.0243902 0.0147059 0.0120482│ │mob2│level2│ │ │ │mob3│level2│ │ │ └────┴──────┴─────┴─────────────────────────────┘ you can then splice it across variables, 'name level isactive v'=:y isactive 0 1 0 so you have converted a table to lists.
- jqpabc123 3mo agoNot everything needs to be an object