Hacker News new | ask | show | jobs
by munificent 2100 days ago
> I wouldn't dismiss the JS ECS frameworks without measurement.

I think the burden of proof is on the part of JS ECS frameworks to show they do have better performance by virtue of DoD and, if so, why. JS engine programmers have been optimizing object-oriented code for literally forty years, all the way back to when they were making Smalltalk VMs.

If somehow a couple of folks hacking on ECS frameworks have managed to write code that runs faster on those JS engines than the kind of code they were designed for, I'd like to see it.

> Having a single type in your array means field accesses, method calls etc. have the potential to be monomorphized.

Sure, but object-oriented code does not require any more polymorphism than DoD does. Consider:

* Iterate over an array of monomorphic components and call a method on each one.

* Iterate over an array of monomorphic entities, access a monomorphic property, and call a method on the latter.

There's an extra property access in the latter (which can easily be inlined), but no polymorphic dispatch. In practice, yes, it is possible to reorganize your JavaScript code in ways that play nicer with inline and possibly even code caching. But I have never seen any evidence that JS ECS frameworks actually do that. Instead, the few I've poked around in seem like typical slow imperative dynamically-typed JS.

If someone is going to take a pattern that was invented specifically for a language like C++ that gives you precise control over memory layout and then apply it to a language that not doesn't give you that control but often uses hash tables to store an object's state, I think the burden of proof is on the framework to show that the pattern actually applies.

2 comments

Okay, here you go

https://github.com/thi-ng/umbrella/tree/master/packages/ecs

Optimized Typescript ECS with a demo rendering 100,000 live 3D particles

That one's pretty interesting. Here you can see they are putting real effort into thinking about the performance of the underlying VM. Using typed arrays is neat.
The author, Karsten Schmidt is one of the most talented devs I've ever seen.

Super nice guy too, always willing to share information or explain stuff to you if he's around.

Modern JS engines won't use a hash table for the object state, they'll use a hidden class, and member accesses will be fixed offset indirect loads guarded by a type check. Initialize your objects carefully in a deterministic order, and I'd expect you can control field order and adjacency.

I'd expect the wins from reworking your JS so that your target JS engine lays out data out better would often be larger than the wins in C++, simply because the worst case is so bad.

I'd add a third option to your pair: iterating over several arrays of properties - especially numeric properties - rather than an array of objects which each have numeric properties. That can get you substantial wins in Java, never mind JS.

> Modern JS engines won't use a hash table for the object state, they'll use a hidden class, and member accesses will be fixed offset indirect loads guarded by a type check.

The type checks themselves have significant overhead, and it's easier to fall off the shadow class fast path than you might expect.

> Initialize your objects carefully in a deterministic order, and I'd expect you can control field order and adjacency.

True, but that's equally true of non-ECS architectures. I have yet to see much evidence that the ECS JS engines I've looked at are actually taking that into account.