Data-Oriented Design in C#: Why Objects Are Slowing You Down
Data-Oriented Design in C#: Why Objects Are Slowing You Down In my previous article, we talked about starving the Garbage Collector by moving away from heap-allocated class types and leaning heavily into struct , Span<T> , and ArrayPool<T> . That’s a critical first step, but it only solves half the problem. You’ve stopped the GC from pausing your app, but you might still be leaving massive amounts of CPU performance on the table. Why? Because of how your data is structured. It’s time to talk about Data-Oriented Design (DoD) . The Object-Oriented Trap We are taught from day one to model our code after the real world. If you are building a social network graph, you might write something like this: public class UserNode { public int Id { get ; set ; } public string Name { get ; set ; } public List < Edge > Connections { get ; set ; } } public class Edge { public UserNode Target { get ; set ; } public int Weight { get ; set ; } } This makes perfect logical sense. A user has connections, and those connections point to other users. But modern CPUs don't care about your logical models. A CPU only cares about reading data from memory into its L1/L2 caches as fast as possible. When a CPU reads a byte from RAM, it doesn't just read that one byte; it pulls a whole 64-byte "cache line" under the assumption that you will probably want the neighboring bytes next. When you loop through a List<UserNode> , traversing from object to object, you are jumping randomly across the heap. The CPU pulls a cache line, reads your data, and then has to go fetch a completely different block of RAM for the next node. This is called pointer chasing , and the resulting cache misses are devastating to performance. Enter Data-Oriented Design: Struct of Arrays (SoA) Data-Oriented Design says: Stop modeling the real world. Model the data the way the hardware wants to consume it. Instead of an Array of Structs (AoS) (or an array of objects), we invert the architecture to a Struct of Arrays (SoA) . If we