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

Inheritance was a premature optimization for computers with small memory. It did its job. However, once memory got big, people forgot to throw it out.

Composition uses a lot more indirection. That's bad on modern CPUs. Pointer chasing throws out performance, so composition is not always preferred, either.




Simple composition, where an entity just has some components on it, can be completely "unrolled" at compile time, essentially removing all indirection as if the entity had all of the data to begin with. You don't need pointers.

For more complex composition, an ECS runtime would likely group all components of the same kind into the same place so that systems that ran with those components get even better data locality.


Composition doesn't imply pointer chasing.

In C++ there is extremely little difference between the code granted for inheritance or composition (unless you use virtual inheritance), so I have no idea what overhead you are talking about.


At least in the case of C#, composition tends to be done via interfaces, which has more indirection than if they were to use an abstract class.

This has been somewhat mitigated in newer versions of runtime.

Not sure what it's like in JVM world, I know they had a better dervirt for a while.


Yeah, but that is a decade later, and also ignores the JIT optimizations like devirtualization, or just like C++ templates, using generics for composition.


> JIT optimizations like devirtualization

JIT devirt can be nitpicky, PGO has improved the situation greatly but until around 6.0 or 7.0 devirt was easy to 'break' in a lot of common scenarios.

Heck, tying into the generic composition bit, ironically static generics still have issues right around devirts. Go figure.




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

Search: