
From native code to browser: Flash, Haxe, Dart or asm.js? - bufo
http://www.infognition.com/blog/2014/comparing_flash_haxe_dart_asmjs_and_cpp.html
======
protoduction
There are other paths for Haxe, although they are probably not pretty. That is
Haxe -> C++ -> Emscripten -> asm.js. Then there is another, Haxe -> Java ->
GWT -> JS.

I think Haxe is underappreciated for areas other than game development. You
can write serverside logic with it (compile to js for node.js, php, neko,
java, c#, python), and target flash and js in the browser.

~~~
sehugg
There's also Java -> GWT -> JS, using libGDX to target iOS/Android/WebGL:

[http://blog.puzzlingplans.com/post/100992521086/building-
a-c...](http://blog.puzzlingplans.com/post/100992521086/building-a-cross-
platform-game-with-libgdx-part-4)

~~~
chii
and don't forget [http://www.robovm.com/](http://www.robovm.com/)

------
christoph
Haxe + Flambe really is a nice combination for developing 2D games for us at
the moment. We cover old browsers with Flash (IE6 etc.) and modern browsers -
either canvas or WebGL, with almost no concern about which ends up running in
the end on the client. It almost feels like magic at times. The compiler also
generally seems very fast as well.

Sublime text makes a nice(ish) IDE with free plugins.

Additionally, we can relatively easily compile out iOS and Android binaries
should we want/need to. It's a very nice system to work with and has caused us
very little problems with just getting things done.

~~~
zubspace
Flambe is really nice. It's well structured and incredibly easy to get into.
In a lot of ways I enjoyed using it more than haxeflixel or haxepunk.

But I never understood why native android and ios games made in flambe require
adobe air... OpenFL clearly wins in this regard.

------
wtetzner
> A lesson to future compiler makers: if you want your compiler to be really
> fast use OCaml, not Java!

Another option the author could have explored is js_of_ocaml. It compiles
OCaml bytecode to JavaScript. It works quite well in my (somewhat limited)
experience.

------
johnyzee
GWT is still a very viable option for writing JavaScript applications, if not
actually the best one. It is one of (or the?) first transpiling tools and very
mature and feature rich (transparent RPC/serialization,
obfuscation/deobfuscation, IDE integrated debugging, i18n, resource bundling,
code splitting, JavaScript interoperability, etc.).

The author seems to have a bit of a bias (Dart's designers "ate too much Java
for breakfast"), but Java is rock solid, and being able to write the entire
application, from the client and the domain model on down to the backend, is a
major boost. GWT also has a vibrant community (see f.ex. the GWT.create()
event across US and Europe: [http://gwtcreate.com/](http://gwtcreate.com/))
and lots of invention and development going on, with a huge new release (2.7)
coming up.

See my game project for an example of GWT in action:
[http://www.webworks.dk/html5engine](http://www.webworks.dk/html5engine)

~~~
cromwellian
You can see asmjs vs flash vs GWT vs Dart vs hand-written JS vs JavaVM vs
compiled C for Box2D here:
[https://plus.google.com/111111598146968769323/posts/e2yJn3QA...](https://plus.google.com/111111598146968769323/posts/e2yJn3QAPSQ)

You can see a chart of size and performance here:
[https://plus.google.com/+BrandonDonnelson/posts/DSUgfWefyR3](https://plus.google.com/+BrandonDonnelson/posts/DSUgfWefyR3)

GWT won on size across the board and beat everything but C on performance. Of
course, this benchmark, like most, is biased. It uses a lot of polymorphism,
and GWT does exceptionally well at removing polymorphic dispatch statically.

~~~
mraleph
> It uses a lot of polymorphism

Are you sure? I have never looked at Java implementation of Box2D used in this
benchmark, but Dart version is definitely not that polymorphic in its hottest
function which corresponds to this Java one:

[https://github.com/jbox2d/jbox2d/blob/76fa2602a6abcbc557c9d5...](https://github.com/jbox2d/jbox2d/blob/76fa2602a6abcbc557c9d50fc4dce578f4585d40/jbox2d-library/src/main/java/org/jbox2d/dynamics/contacts/ContactSolver.java#L336)

It looks like mostly a bunch of floating point math to me with not that many
calls out.

Another interesting thing I noticed now is that Java version has all vector
math inlined manually, while in Dart version it is not the case (at least not
entirely if I remember correctly - we want to write high level code and let
optimizer do what it can).

~~~
cromwellian
No, I'm not sure. I profiled the hand-written JS function one time and noticed
a lot of time spent in polymorphic methods. Also, this coincided with an
optimization in GWT to improve hidden class V8 optimizations and speed went up
by 300%, so it seemed related to polymorphism.

The vector math does look like an apples-to-oranges comparisons. Simple
methods like cross-product will inline in GWT as well. The biggie seems to be
the elision of the temporary, we'd need something like C++'s return value
optimization to get rid of that.

I'll try rerunning the bench by adding calls to cross-product to see how it
fares. Actually for us, we weren't as interested in comparing the speed to
Dart as much as comparing it to the JVM version. The slowdown there is on the
order of 50% which isn't bad. In the original thread on G+ I noted there's no
way this can be considered an apples-to-apples comparison because they're not
running the same code (the port's from Box2D differ), but Joel's whole Box2D
benchmark suite kind of rests on this.

~~~
mraleph
> I'll try rerunning the bench by adding calls to cross-product to see how it
> fares.

btw, if you have a moment I would really appreciate if you tell me how to
reproduce +Brandon Donnelson results. It's hard to figure out from those
photos which version of GWT should I get from where and what to compile with
it. I was not sure if I supposed to check out Joel's code AS IS or I should
get it from some other place, etc.

~~~
cromwellian
It's been a while, but you'll probably need to built a custom version of GWT
using this patch ([https://gwt-review.googlesource.com/#/c/8590/](https://gwt-
review.googlesource.com/#/c/8590/)) as we had to roll back the V8 optimization
due to a catastrophic performance regression in IE11.

Then you'll need my fork of Joel's repository here:
[https://github.com/cromwellian/bench2d](https://github.com/cromwellian/bench2d)

I'm not sure they were upstreamed into his.

Brandon's results were culled from the informal results I posted in Joel's G+
thread (which he independently verified). From the thread you can see I was
quite disbelieving myself and not at all ready to plant a flag, I even
implemented a verification in the GWT version to ensure that the final resting
state of the system converged to what it was supposed to.

Some very tiny patches to GWT (adding dummy random unique properties to
prototypes, an optimization to HashMap.put/ArrayList.get, etc) have lead to
300-500% speedups in our benchmark server, meanwhile really complex ones
actually slowed things down, or did nothing.

For example, I added asmjs output to GWT (where possible in method bodies, not
a truly strict-check), I also implemented an optimization which auto-converts
Java classes to typedarrays where possible, e.g.

class Vec3 { float x, y, z; // getters and setters }

Would require the class into a bag of static methods and rewrite the field
accesses into indexes into a typed array. This turned out not to be a win when
benchmarked on Box2D, probably for other reasons.

:(

~~~
kevingadd
Interesting, why the dummy random unique properties? Some sort of type
information/hidden class pollution workaround?

Converting classes into typed arrays/typed array buffers is something that
seems like it should be awesome but in practice isn't. :( I've tried it
extensively in JSIL as well and it seems to only be a win if you have
thousands of them in an array - for individual instances you get murdered.
Maybe this will get fixed by Typed Objects if they ever land in ES.

~~~
cromwellian
I am very interested in better ways to transform Java into asmjs, but I think
we'll need typed objects and/or some way to deal with garbage collection. The
latter is a particular problem, well, if we take the route we did with j2objc,
we can just punt and require manual annotations to break reference cycles,
implementing our own ref-counting/ARC scheme on top of typed arrays, but it
would be nice if someone asmjs and GC could play nicely together, without
implementing the Boehm collector. :)

~~~
kevingadd
Well, I have a relatively firm plan to work on getting asm.js v2 + typed
objects finalized and produce a proof-of-concept compiler targeting them, so
hopefully I can help push them along! It'd be great to understand GWT's needs
here.

~~~
cromwellian
I didn't notice that the Typed Object spec supports "new" heap allocation, if
this'll work with asmjs, than awesome.

GWT's needs are primarily two fold: 1) recognize Java types that can be
promoted to struct-types. GWT already knows how to do this as it has passes to
convert all methods of a class to monomorphic/static dispatch, meaning the
prototype only has to contain field values. Thus if a Java type has no
polymorphic methods, and all fields are either primitives, or references to
other 'struct' types, then the compiler can emit typed objects.

2) Since Java is a GC'ed language, GWT currently isn't in the business of
implementing a memory management scheme. We rely on Javascript to do this. The
current problem with strict asmjs output is we'd need to allocate typed arrays
and our own memory management scheme. There's not much appetite for that right
now, but I suppose it could change in the future.

------
espadrine
> _I don 't know how exactly Emscripten handles the uints question but
> everything worked well and pretty fast without me having to worry about it
> and having to turn uints into ints._

Isn't that a bit cheaty? IE is potentially a lot faster with that change,
which Haxe's port benefits from. Haxe's port got more work put into, so
proclaiming it a winner because Emscripten was already pretty fast without any
work put into the port makes me doubtful of the results.

(Also, Haxe's UInt 0xFFFFFFFF not being converted to -1 sounds like a bug
waiting to happen.)

------
TazeTSchnitzel
Haxe's compiler speed probably isn't from OCaml, and rather from a much
simpler compilation process than is necessary for Dart or emscripten.

~~~
agersant
What makes you think Haxe is simpler to compile than these two?

~~~
TazeTSchnitzel
Hmm, well. For emscripten, the code is run through the C preprocessor, then
clang and LLVM have to sucessively "lower" it several times, and then generate
asm.js.

Haxe, on the other hand, is a high-level language that could be compiled to
JavaScript much more simply.

But then, I'm not sure why Dart would be slow, then, given it's also quite
high-level. Tree-shaking of the standard library? Having to compile the
standard library?

~~~
seabrookmx
Haxe is multi-targeted. It compiles to PHP, C++, Neko Bytecode, etc.

Being a high-level language, and using the same compiler infrastructure, it
would have to be transpiled into a fairly low-level IR for the consumption of
the various backends before being spit out as JS again.

I think the fact that its high level makes it much LESS simple.

It definitely isn't just mapping Haxe constructs to JS. It is much too feature
rich.

------
Pharohbot
For Dart, it wasn't fully valid. The problem was that they used the 32-bit VM
on a 64-bit machine. Of course, the Dart team is working on fixing the number
boxing on the 32-bit version that resulted in the poor performance, but the
64-bit performance would've been better, as outlined in the article.﻿

------
amelius
It would have been nice to see NaCl in a side-by-side comparison with asm.js.

~~~
TazeTSchnitzel
NaCl would be somewhat faster in Chrome, and would be infinitely faster in all
other browsers, as no code executes faster than no code at all!

------
bigredhdl
Thanks for sharing. I leaned a lot from your comparison.

