Firefox 9 uses type inference to improve JavaScript performance by 20-30%
extremetech.com
extremetech.com
JavaScript isn't weakly typed, you can't for example "cast" a number to a string. There is automatic coercion but that's a different thing. I think he means dynamically typed in this case, that or duck typing.
> Type inference fills in the gap between strong and weak typing so that you can still write sloppy code, but reap some of the speed boost.
I don't even know what to say about this. Following this faulty logic might lead one to believe that Haskell has type inference to make all that sloppy Haskell code perform well. Type inference doesn't have anything to do with strong and weak typing, it has to do with manifest and implicit (or inherent) typing.
I don't get how the type inference remark is faulty logic either. Haskell is orthogonal because it is statically typed, but type inference when applied to dynamically typed languages certainly can provide a performance boost.
Which is funny because your first link states: "In C++, a weakly typed language, you can cast memory to any type freely as long as you do so explicitly."
I'm pretty sure the last time I read that article it said that there is no generally accepted definition of weak typing. This discussion seems to echo that.
Agreed. There ARE definitions but they aren't terribly specific, useful, or even very consistent. Funnily enough, the wikipedia article on strong typing includes C and C++ as an example of strong typing.
In this case anyway, I think it's clear that the author was really talking about the static vs dynamic distinction, and should have used those terms instead:
> Some languages are strongly typed, which means that the programmer must define the type of every class, function, and variable that he uses; tiresome, but it can have big pay-offs in terms of overall speed. Other languages, like JavaScript, are weakly typed, which means that the programmer doesn’t have to worry about such piffling minutiae; you can just write some code and let the compiler do the heavy lifting.
So to be more accurate, he was comparing explicit static typing with dynamic typing.
In fact if a language is strongly typed not defining anything will not necessarily have an impact on speed because it is possible to infer types statically at compile time like GHC does for Haskell.
In other words: I think we agree.
I understand the importance of defining thing correctly, but does the average person need to care or worry about the difference between strongly/weakly typed & statically/dynamically typed?
One thing I'm curious about as a developer is how this is different than the type inference that SpiderMonkey already did. The JIT certainly didn't represent numbers as strings in memory or something equally silly prior to this new type inference. Is it better inference that optimizes away boxing or can optimize across function calls or something?
(Just musing "out loud", I don't expect answers to these questions here on HN.)
>> Type inference fills in the gap between strong and weak typing so that you can still write sloppy code, but reap some of the speed boost. >I don't even know what to say about this. Following this faulty logic might lead one to believe that Haskell has type inference to make all that sloppy Haskell code perform well. Type inference doesn't have anything to do with strong and weak typing, it has to do with manifest and implicit (or inherent) typing.
I'm not sure even manifest typing would be the correct term as he mentions performance. So it looks like he is looking for static vs dynamic.
Dynamic typing but inferring types statically where possible. It is interesting that type inference in a statically typed language leads to less noise and type inference in a dynamic language leads to some speed boost.
(Scroll down to the 'Type Inference' section)
And somewhat more technical (although mostly about IonMonkey) here: https://bugzilla.mozilla.org/show_bug.cgi?id=650180
-edit- Found actual 'Type Inference' bugzilla discussion: https://bugzilla.mozilla.org/show_bug.cgi?id=557407
First, making it fast is extremely difficult. JavaScript compilers are under extreme pressure to compile code quickly, unlike any other type-inferring compiler, because JS compilation keeps the user from seeing the page.
Second, in order to be useful, type inference for JavaScript has to be speculative. JS's semantics require that ints overflow into doubles, for example, meaning that a conservative type inference engine would have to assume every number can potentially be a double. This is too imprecise to be useful, so the inference engine speculates. If the engine guesses wrong, the compiler must not only recompile the function under the new assumptions but also (since this is a global analysis) potentially update every other function that the function called.
Finally, the presence of eval() and the like mean that almost no inference can be totally sound, requiring even more dynamic checks.
There's a reason that (despite what some others are saying in this thread) V8 and Chakra haven't done this yet: it takes a long time to get right.
Static type inference may even allow for doing away with some, if it's possible to statically prove types are fully known at compile time for a code section.
I'll be curious if it's good enough to enable by default, or if the developer needs to flag the engine somehow to enable the feature.
You only run type inference after you detect the hot loops. Same with other expensive optimizations. This is something that all JITs out there do -- you start with simple interpretation (or extremely cheap compilation, in the case of V8), and then when you detect that you're spending a whole lot of time in one section of code, you replace it with a highly optimized version.
Type inference is not that expensive compared to several more interesting optimizations done on several JITs that are in production systems. In some long running JITs, the compilation of some hot loops takes far longer than static compilations, running in a low priority thread in the background (while the less optimized code keeps going in the foreground).
Finally, if anything, JITs allow more time to run heavy optimizations because they can leave those running in the background without affecting the use of the program or hurting developer productivity.
> JS's semantics require that ints overflow into doubles, for example
On recent x86 processors, you would just use doubles in most cases. It turns out that they're on par with integers for speed, although I believe there were some differences on latency. I'd have to look back at the Intel opt manual to confirm, though. However, if you really want to solve the issue (say, on ARM where integer/float performance actually matters -- especially since lots of architectures are still on softfloat), then you'd use a combination of guards, versioning, and VRP to solve the issue, not type inference.
> Finally, the presence of eval() and the like mean that almost no inference can be totally sound, requiring even more dynamic checks.
Yep, eval is a terrible language feature if you care about making things fast. Regardless of whether you have type inference or not.
That is the traditional approach, yes. But it will only get you so far. If you just analyze the current piece of code, you will miss out on a lot of potential optimizations.
For example, the types of the variables in the current function may be always of the same type, but without analyzing all the callers you wouldn't notice that - which means you would need to check the type each time you enter. With a more global analysis you could detect that once and be much faster.
There are a lot of other optimizations of that sort, like global variables - you can prove statically the type of many of them, just by looking in the whole program.
What is cool about this new Type Inference engine is that it is a hybrid approach. It does both local and global, and both static and dynamic analyses. You are very correct that local/dynamic type inference is a known thing, and JITs like TraceMonkey have done a form of it for a long time. But this new engine is something much better.
I didn't say that you only analyze the current piece of code. Type inference is, by nature, a global optimization. However, you don't do it until you've identified the hot spots, and you've established that it's worth investing time into it.
First, however, you get something quick running so that there are no delays, and the cost doesn't matter much to the user.
This is especially the case in the common situation of code computing array indices. Since those end up being treated as integers in the end, if you have them as doubles for the arithmetic step you have to keep paying double-to-integer conversion costs. The same considerations apply for some DOM methods that take an integer, and similar considerations apply to cases when numbers need to be converted to strings (e.g. when setting .style.top on an element): this is a lot cheaper to do for integers than for doubles.
Integer operations have 2-3x the throughput and 4-5x better latency than floating-point operations on recent Intel CPUs.
I guess it comes down to how effectively you can schedule stuff.
Chakra (IE9) already has it, I think.
http://blogs.msdn.com/b/ie/archive/2010/03/18/the-new-javasc...
The big thing that IonMonkey is adding is type inference through static analysis, which is a big deal for JavaScript.
Crankshaft uses type feedback, not type inference. Ie: it will monitor the types of objects to generate type-specialized code, but will not do static type inference on the code to generate type-specialized code.
Mmm.. I think they've forgot to factor in the ratio of JavaScript involvement in overall web surfing experience?
But it's nice to see that the race is still on, with each browser leapfrogging the others every once in a while.