As a baseline, here's the first benchmark running in C:
Code: Select all
Time(a) = 1451.45 ms (benchmark - SimpleTerrainCircles_1000)
Code: Select all
$ node bench.js
SimpleTerrainCircles 1000
Run 1: 22426
Run 2: 21808
Using v8 head (v8: 3.19.18.5):
Code: Select all
$ ../v8/out/native/d8 bench.js
SimpleTerrainCircles 1000
Run 1: 11248
Run 2: 12930
Emscripten (-O2 -DNDEBUG), v8: 3.19.18.5 in Chrome Canary:
Code: Select all
Time(a) = 3967.12 ms (benchmark - SimpleTerrainCircles_1000)
In Firefox 22 (which has asmjs support) (Firefox nightly (25a) has about the same performance):
Code: Select all
Time(a) = 2044.10 ms (benchmark - SimpleTerrainCircles_1000)
The V8 team is actively working on making asmjs code run faster in v8. They don't want to have a special 'asm.js mode' like firefox does - instead they're adding optimizations which can kick in for asmjs-style code (source: insiders on the Chrome team). I expect Chrome performance to catch up to firefox performance in the next ~6 months or so.
Notes:
- I didn't make any changes to chipmunk (although I did bump chipmunkjs tests runs back up to 1000 to match chipmunk). My test code is here: https://gist.github.com/josephg/5892575
- I compiled the benchmark code from C using emscripten. If your game is written in javascript, performance will be worse than this.
- These numbers are approximate. I didn't run the benchmarks multiple times and I have a million things open on my machine. I doubt they'll be off by more than ~10% though.
- Downloaded filesize increases by nearly 3x. Chipmunk-js is 170k, or 17k minified & gzipped. With emscripten the output is 300k, minified & gzipped to 49k. This is way bigger.
- We can expose most of chipmunk directly to javascript. Unfortunately, we can't share vectors from inside the emscripten environment and outside of it - emscripten (obviously) inlines vectors inside its own heap & stack. In javascript, the best we can do is use objects in the JS heap. Our options are either removing vectors (as much as possible) from the API (cpBodySetPos(v) -> cpBodySetPos(x, y)), writing some javascript wrappers around everything to bridge between a javascript vector type and a C vector type or putting vectors in the emscripten heap (which would be faster than a JS bridge, but require that you match cpv() calls with cpvFree() or something. All options are kind of nasty.
- Emscripten doesn't use the GC, so you can now leak memory if you don't cpSpaceFree(), etc.
- As well as running faster, its easier to port code like this. Keeping chipmunkjs updated with the latest version of chipmunk should mostly just require a rebuild.