It's not really a fair comparison as the dart versions are more-or-less completely statically typed. If they wanted this to be fair they'd be using untyped (typing is "optional" in dart).
If you're allowed to modify the code in substantial and performance altering ways for one language, you should be allowed to for the other as well (the JS versions of both those benchmarks have substantial perf problems).
This is especially egregious given that the DeltaBlue tests is ported from untyped smalltalk, so the JS version is actually closer to the original.
Dart is actually not statically typed: in production mode (which is default) type annotations are ignored completely, in checked mode they are translated to runtime type guards and not checked globally&statically during compilation. For more details please take a look at: http://www.dartlang.org/articles/why-dart-types/
Published benchmark scores are coming from the production mode. Even if you remove all type annotations performance will not change a bit.
In fact by design Dart VM does not use any information provided in type annotations to perform optimizations.
Dart is not statically typed, the types are erased at runtime. i.e. There is no semantic difference to the running program with a Dart program that has types specified with one that does not.
The static type annotations are for Developer documentation only and are ignored by the VM.
The Dart team came from the V8 team, and presumably they're still involved in V8. I'd expect any optimizations that were developed for Dart and were applicable to JS would be backported into the V8 engine, so there must be something different about the Dart language that enables more optimizations.
From what I've seen of Dart, if you ignore the type annotations (like the VM does), and you don't consider syntax, the only performance-relevant difference between JS and Dart is the OOP system, which wouldn't explain a 50% performance difference...
Dart also has more sane operators (e.g. ==), no implicit conversions, no prototypes, types are not mutable, scopes are not mutable (including globals), a real integer type, lack of "arguments", lack of "eval"/injected <script> tags, Strings don't need to support fast concatenation (there's StringBuffer), and probably a bunch more things I'm forgetting :)
Disclaimer #1: lack of mutable types/scopes might change in the future with mirror builders. Presumably mirror builders will be structured in such a way that they cause minimal effect on optimizations.
Disclaimer #2: I don't work on the VM so take this FWIW.
"As VM engineers, the designers of Dart know how to build a language for performance. A more structured language is easier to optimize, and a fresh VM enables improvements such as faster startup."
Unlike JavaScript, Dart was created with performance (and tooling) in mind. There are a few people involved who worked on several VMs such as HotSpot or V8. JavaScript didn't have that kind of guidance. There are some features in JavaScript which make optimizations very difficult or even next to impossible.
The most obvious ones are probably `eval`, `with` (each property can mean something different with every iteration), and messing around with `arguments` (changing values of that pseudo array also changes the values of the actual named parameters).
You can also change, overwrite, and delete everything. `this` can also refer to something different each time.
Those quirks make JavaScript VMs very complicated and they also result in many surprises. For example, using `delete` can degrade performance quite a bit and adding properties to built-in objects can break some optimization-related heuristics.
Dart just skipped all of that really nasty stuff.
Well, to be fair, they also skipped one of the very useful nasty parts: on-stack replacement (OSR). If there is just one long-running function it won't get optimized (it won't get replaced - right there on the stack - with an optimized version).
Generally, this doesn't matter much, but there are some cases where it's really inconvenient.
It's safe to assume that they will address this once they are done with all optimizations they deem more important. I'd guess it will happen before they hit the big 1.0 (M1 = 0.1-ish).
> very useful nasty parts: on-stack replacement (OSR)
...
> Generally, this doesn't matter much, but there are some cases where it's really inconvenient.
One could argue that every application which would benefit from OSR is essentially a micro benchmark.
I can't disagree with that, because that statement is absolutely true. The only difference between those two kinds of programs is the intention of the programmer. In both cases you have at least one heavy function which is called just once. As far as the VM is concerned, there is no difference whatsoever.
But it's also true that there are sometimes long running functions which are aren't frequently called. In Java, JavaScript, or C# you won't have to worry about that kind of thing. You won't have to break it down in smaller pieces just for the sake of spreading the load across more function calls.
My point is: you don't have to worry in Dart either. If the code you are shipping is suffering due to the lack of OSR and you have to work around that --- just add an example to the bug and we will fix it.
10 comments
[ 3.5 ms ] story [ 32.7 ms ] threadIf you're allowed to modify the code in substantial and performance altering ways for one language, you should be allowed to for the other as well (the JS versions of both those benchmarks have substantial perf problems).
This is especially egregious given that the DeltaBlue tests is ported from untyped smalltalk, so the JS version is actually closer to the original.
Dart is actually not statically typed: in production mode (which is default) type annotations are ignored completely, in checked mode they are translated to runtime type guards and not checked globally&statically during compilation. For more details please take a look at: http://www.dartlang.org/articles/why-dart-types/
Published benchmark scores are coming from the production mode. Even if you remove all type annotations performance will not change a bit.
In fact by design Dart VM does not use any information provided in type annotations to perform optimizations.
The static type annotations are for Developer documentation only and are ignored by the VM.
The Dart team came from the V8 team, and presumably they're still involved in V8. I'd expect any optimizations that were developed for Dart and were applicable to JS would be backported into the V8 engine, so there must be something different about the Dart language that enables more optimizations.
From what I've seen of Dart, if you ignore the type annotations (like the VM does), and you don't consider syntax, the only performance-relevant difference between JS and Dart is the OOP system, which wouldn't explain a 50% performance difference...
Disclaimer #1: lack of mutable types/scopes might change in the future with mirror builders. Presumably mirror builders will be structured in such a way that they cause minimal effect on optimizations.
Disclaimer #2: I don't work on the VM so take this FWIW.
"As VM engineers, the designers of Dart know how to build a language for performance. A more structured language is easier to optimize, and a fresh VM enables improvements such as faster startup."
The most obvious ones are probably `eval`, `with` (each property can mean something different with every iteration), and messing around with `arguments` (changing values of that pseudo array also changes the values of the actual named parameters).
You can also change, overwrite, and delete everything. `this` can also refer to something different each time.
Those quirks make JavaScript VMs very complicated and they also result in many surprises. For example, using `delete` can degrade performance quite a bit and adding properties to built-in objects can break some optimization-related heuristics.
Dart just skipped all of that really nasty stuff.
Well, to be fair, they also skipped one of the very useful nasty parts: on-stack replacement (OSR). If there is just one long-running function it won't get optimized (it won't get replaced - right there on the stack - with an optimized version).
Generally, this doesn't matter much, but there are some cases where it's really inconvenient.
It's safe to assume that they will address this once they are done with all optimizations they deem more important. I'd guess it will happen before they hit the big 1.0 (M1 = 0.1-ish).
If you have a real world application [not a microbenchmark] that suffers from the fact that Dart VM does not implement OSR please add it to https://code.google.com/p/dart/issues/detail?id=6787
I can't disagree with that, because that statement is absolutely true. The only difference between those two kinds of programs is the intention of the programmer. In both cases you have at least one heavy function which is called just once. As far as the VM is concerned, there is no difference whatsoever.
But it's also true that there are sometimes long running functions which are aren't frequently called. In Java, JavaScript, or C# you won't have to worry about that kind of thing. You won't have to break it down in smaller pieces just for the sake of spreading the load across more function calls.