10 ms·
I used to believe that javascript was slow, C was fast and that there was no way to change this because of the way that javascript is interpreted and not compil
by barbegal 8y ago
I used to believe that javascript was slow, C was fast and that there was no way to change this because of the way that javascript is interpreted and not compiled. But the more I've learnt about the benefits of "on the fly" / "just in time" optimising compilers, the more I'm convinced this is the future of computing. Being able to use multiple threads and hence multiple cores simultaneously to optimise what is actually a single threaded piece of code is quite amazing. And then being able to write code that is insanely portable and optimised on any platform is great.You can take advantage of SIMD, hyperthreading, multicore, large caches... without knowing if they're available ahead of time.
Sure, you won't beat C for low memory devices or hardware that you have complete control over but for 90% of use cases javascript actually makes sense and can be the most performant.
- saagarjha 8y agoThe key being that the code you're writing needs to be performant. If you write O(n!) code, it's going to be slow whether it's C or JavaScript.
- stochastic_monk 8y agoAlgorithms take you far. Optimized code takes you the rest of the way. If you’re after performance you’ll do both, of course. I’ve found that the only subfield of which I know in which mathematicians still write their own C or C++ is concise/efficient data structures and algorithms.
- wolf550e 8y agoWelcome to 1995 and the wonderful world of Java. Except in Java you can use threads to use multiprocessing, so you can have efficient shared data structures but also hard to debug bugs.
- stochastic_monk 8y agoC++ also does this. A variety of projects, such as MXNet, use JIT compilation. Native compilation gets you far, but there are times where dynamic compilation gets you farther.
- lovelle 8y agoI would argue that in 95 was recently the first jdk 1.0 release, it was until 2004 which came java 5 with java.util.concurrent which was such huge improvement for that time, since then is easier to write concurrent software, and since java 8 is a wonderful experience!
- emp 8y agoDon’t forget 1987 and the Self language from which Java got Hotspot. Fascinating language and runtime: http://www.selflanguage.org http://www.selflanguage.org
- chrisseaton 8y agoIn my group at Oracle we're experimenting with running C using the same just-in-time compilation techniques that JavaScript uses, and sometimes we see it running faster than ahead-of-time native compilation, due to the effects of things like inline caching and profiling.
- chii 8y ago> sometimes we see it running faster than ahead-of-time native compilation, due to the effects of things like inline caching and profiling. which is what java touts as being able to do. Unfortunately, i think this sort of speedup is really dependent on the application (and the developer using common idioms that is recognized by the JIT).
- ehsanu1 8y agoI suppose you're talking about sulong? https://github.com/graalvm/sulong https://github.com/graalvm/sulong Pretty cool that it can run faster than AOT compiled C, any benchmarks or posts with more details on this?
- zzzcpan 8y ago> sometimes we see it running faster than ahead-of-time native compilation Edge cases. But obviously it's not comparable to something ahead-of-time compiled and hand profiled with PGO and stuff. Although in theory you could put that through JIT too, but it would probably just add overhead and only slow things down.
- mpweiher 8y agoReports of some jitted Java code running faster than C (after warmup) are old. I remember seeing those claims for some super hot VM in the old IBM System's journal from 2000, and yes, IIRC that was a VM written mostly in Java. However, those isolated examples rarely if ever translated to high performance in real-world projects. The same issue has an experience report of the travails of IBM's San Francisco project. Performance was a huge issue that to the best of my knowledge they never fully resolved. More in my article "Jitterdämmerung": http://blog.metaobject.com/2015/10/jitterdammerung.html http://blog.metaobject.com/2015/10/jitterdammerung.html
- Negitivefrags 8y agoThe difference in speed has a lot more to do with memory layout. Javascript will never be as fast for this reason. You could make a JIT language as fast as C so long as it supported value types properly. Most programs in the "slow" languages spend most of their time chasing pointers around.
- goatlover 8y agoJulia comes fairly close.
- ChrisRackauckas 8y agoAnd Julia's tuples, named tuples, and structs are value-types without pointers.
- weberc2 8y agoTo elaborate on your point, its not just chasing pointers, it’s that those pointers point into random heap locations, each of which needs to be allocated individually and garbage collected. Also, because of the haphazard locations of these objects in the heap, you have way more cache misses than you would with value types.
- millstone 8y agoWhat do you mean by "multiple cores to optimise a single threaded piece of code?" This makes it sound like code can automatically become multithreaded which is not true (threading is one of JS's great weak points). v8 is an amazing piece of engineering but it's not at the point where it allows application developers to take much advantage of SIMD, hyperthreading, or multicore.
- Scarbutt 8y agoWhat do you mean by "multiple cores to optimise a single threaded piece of code?" I think he means this is done behind the scenes without your knowledge (some compiler/runtime magic), not some interface you can take advantage of.
- acchow 8y agoYou also can't beat C for energy efficiency. That JIT consumes energy.
- wvenable 8y agoI feel everyone ping-pongs between these ideas; I've been there and I'm no longer convinced the way you are. You can't take single threaded code and just make it multithreaded no matter how much time the compiler spends on it. And in a JIT environment, the compiler doesn't actually get much time to spend optimizing code. You can't just take advantage of SIMD, hyperthreading, multicore, or large caches without writing code in a way that takes advantage of that even at a high level. Some things can be faster when compiled at runtime but everything is a trade off. But ultimately I believe that C is fast mostly due to manual memory management but that's not a trade-off I'd take for most tasks.
- repolfx 8y agoI think his point is that if you write normal single threaded code then your other cores are going to be idle. But if you write in a high level JITed GCd language then the other cores will be busy making your main thread run faster by profiling it, recompiling it with risky optimisations, clearing garbage asynchronously and so on.
- zzzcpan 8y ago> take advantage of SIMD, hyperthreading, multicore, large caches... without knowing if they're available ahead of time You can't with Javascript. You need concurrency-friendly programming model and code structure for compiler to be able to do anything that fancy.
- delinka 8y agoA couple of the replies here seem to read that you've said something like "JIT magically makes single-threaded code multi-threaded." I'm a little mystified by the reading comprehension on HN... You can write a multi-threaded optimizer that works on single-threaded code. Using multiple threads on multiple cores to optimize single-threaded code ... is pretty darn cool, but barbegal never said it made the single- into multi- ...
- MikeHolman 8y agoThe reason most of the features of the JIT are needed is due to the lack of static typing in javascript. The most important thing the JIT does is figure out what types of things you are using and optimize for them. There will always be some cost here, because at runtime you need to check if your assumptions still hold. Some of the time you can pull these checks out of loops, but sometimes you can't, and they can be costly. There are a few things a JIT can theoretically do better. Inlining is the biggest one. For example, a JIT knows not to inline a function that never gets called, and it can also do inlining for indirect calls based on profile data. A JIT could also theoretically move unexecuted blocks out of line for better instruction cache locality. It could also check for aliasing at run time (with a bailout) and then optimize a loop assuming no aliasing. Unfortunately for JITs, AOT compilers can do a pretty good simulation of most of these things with PGO, that is running a scenario with an instrumented binary and re-optimizing using profile data. Still can't bailout if an assumption is wrong, so it doesn't work for dynamic languages, but you don't really need bailout for much in static languages.
- 0xcde4c3db 8y agoKeep in mind that a lot of performance differences come out of the snowball effect of popularity driving product development. X86 being faster than MIPS today has nothing to do with the relative merits of the ISAs and everything to do with the millions of people who wanted to run X86 code really fast for the past 25 years. JavaScript's foray into this scale of popularity is pretty recent, with the widespread adoption of "Web 2.0" and AJAX only dating back to about 2005 (both are older, but spent a while in the throes of obscurity and incompatibility).
- pseudocook 8y agoI used to be a Smalltalk developer on Windows 3.1 for a brief time in the early 90's. When I found out that internally, Smalltalk was compiled into a sort of intermediate assembly language, and run on a virtual machine, I wondered why couldn't we just distribute the assembly language part over the Internet, where it could be run on any kind of machine with an interepreter. Everyone told me I was crazy, it was impractical, it would never work.
- ioquatix 8y agoYou are crazy, it is impractical, it will never work. /s
- stcredzero 8y agoI used to work for a Smalltalk vendor. It was even better than that. For awhile we had the hottest JIT virtual machine. Smalltalks that followed the original design ran bit identically across multiple platforms. At one point, Squeak Smalltalk was running bit identically across 50 combinations of CPU and OS, and Squeak and its descendants probably can run bit identically across several times that number of environments now. But it gets even crazier. (Non-Smalltalk) In the 90's, there was an OS entirely written in a virtual Instruction Set (TAOS) which was JIT assembled into real machine code as fast as it could be read off of disk and ran at 80-90% of native speeds. This OS could be ported by simply porting the assembler, which typically took about 3 days. Back to Smalltalk craziness. There were also in-house research versions of Smalltalk that could prune their images as small as 45k, and were suitable for creating command line tool executables. As it was, VisualWorks, if you turned off things like the splash screen, actually could start faster than the Perl runtime in the late 90's, though you'd be hard pressed to create an image below 500kB. (Even getting it below a megabyte was an incredible feat.) The tech industry could be way ahead of where it is now, if only everyone were like early adopters. The thing is, most people are quite different.
- FridgeSeal 8y agoWow that sounds super, super cool! As you say, I really wish tech had followed that route, think of all the cool things we'd have.
- ams6110 8y agoWhat's funny to me is how JavaScript has gone from something of a joke to a very well regarded, performant, and heavily used programming language. I can clearly remember the days when proposing any significant programming in JavaScript would get a developer laughed out of the room. Is there another example of a language that has had such a 180 degree turn around in respect and popularity?
- mamcx 8y ago> respect Not much respect, but more acceptance as a unavoidable language to use that thanks of millons of $$$$/human-hours of effort to polish it... is ok-ish.
- always_good 8y agoI'd say it's no worse than Ruby or Python. Async-everything is what makes it better, imo. No need for Twisted/EventMachine fragmentation. This is how people end up using it on the back-end when they do have a choice. Though "respect" is a corny word to use for any language. I don't respect my screwdriver either.
- qaq 8y agoModern JS is OK and TS is pretty nice
- eksemplar 8y agoYou don’t achieve acceptance without a level of respect that comes from being useful. JS is really one of the most useful languages today. You can argue whether everything moving to web apps (and I may be using the term web apps wrong, but I’m speaking about anything that runs in a browser) is such a good idea, it’s probably not, but it’s whats happening because it’s really fucking awesome in terms of getting things to actually work across multiple devices. JS does something none of the other tech stacks does, in that it integrates really well with your current stack. I work in enterprise, we operate more than 500 different it systems, and most of them run on windows. So natural,y our operations ninjas are really great at Microsoft tech. Operating ruby, PHP, python and so on can certainly be done within the windows environment, but we’ve naturally been doing .net since it fits in better. JS fits into this infrastructure perfectly. A lot of it is thanks to MS, but we haven’t had to spend money on retraining staff to integrate modern JS into our stack. The language itself offers a lot of freedom, which includes risk, but I don’t personally think it’s worsening that regard than python.
- josephg 8y ago> javascript actually makes sense and can be the most performant. Thanks to V8 you can definitely achieve good enough performance with JavaScript for most applications, and the ergonomics are pretty great. But it’s not true that performance rivals or beats C in the general case. The ‘sufficiently advanced compiler’ rainbow is something that Java has spent decades chasing. I think it’s fair to say at this point that humans are better at writing C code than we are at writing clever compilers. It’s many of the exact ergonomics which make JavaScript useful and easy to use that also make it much harder to optimise. For example, what code should V8 generate for `x+=x` ? The optimiser might find that x is always a positive integer, but every time it gets doubled, it might cross the magic overflow point where it needs it’s representation swapped for a double. The generated code must check for this every time. Or consider memory management - For games I’ve heard of people making a per-frame arena allocation pools for values with a lifetime that won’t cross frame boundaries. This basically makes these allocations free and improves cache coherency. I’m happy that the JS GC is multithreaded now, but there’s no way a GC can compete with that. And unlike C, there’s no way in JS to override the allocation behaviour. There are a million paper cuts like this which lower the ceiling of how fast optimised JS can run. I’m glad V8 will keep improving, but for my money the future of really fast JavaScript is Webassembly.
- azhenley 8y agoYou make some interesting points about cases where JS will always be difficult to be optimized automatically. I wonder if compiler hints can help in that regard? For example, if performance is important then you could annotate the 'x+=x' line to tell the compiler to not check for overflow.
- Thiez 8y agoSure, you can hint with OR: `x = x | 0; x = (x + x) | 0;`. Bitwise operators always work on 32 bit integers in js. I'm not sure whether the js vms actually need or use this information.
- amelius 8y agoAnother option would be that the compiler deduces when exactly the statement x+=x would need to switch from integer to double. That's more difficult, and impossible in general, but not impossible in specific cases.
- nitwit005 8y agoTry profiling a few Javascript applications vs equivalent C applications, and you'll probably become significantly less sanguine.
- repsilat 8y agoI agree, though you'd be surprised at the difference in attitude between developers in each language. I think JS is now within a factor of five of C, but JS programmers are significantly more blase about performance. In many cases they won't blink at a quadratic algorithm when a linear or nlogn one is possible, provided the quadratic algorithm is cleaner. Ditto constant factors -- a C programmer might go out of their way to not iterate over a string more times than necessary, and a JS programmer won't. A C++ programmer might try to minimise lookups into a map, and a JS programmer won't. Some JS shops strongly encourage `array.forEach`, which is 6-7 times slower (on my machine) than an "old-school" `for()` loop. For most web apps it makes no difference, but if performance ever does become a problem it can make it harder to fix. In my experience, profiles in "fast" languages in codebases written in the traditional paranoid style tend to be "lumpier" than profiles in "slow" languages written in the fashionable cavalier mode. None of this is to judge anyone. I think being lazy and implementing an O(n^2) algorithm is perfectly reasonable when you know n is always going to be small, but I am cautious -- as much as the increased productivity is fun and addictive (and real in my day-to-day work), I've also seen the death by a thousand cuts first hand.
- rco8786 8y agoIt’s not really the future. It’s the literal now.
- physguy1123 8y agoSIMD, multicore, and caches don't just magically happen with better compilers. SIMD requires very specific memory access and computation patterns, and cache-friendly code has similar restrictions. The features of even basic javascript fly in the face of code being simd and cache friendly except for the most trivial programs. Automagically parallelizing general serial code is something that isn't feasible on any hardware similar to modern cpus and probably will never mesh well with fast single-threaded performance (communication and synchronization in hardware is HARD)
- flukus 8y ago> but for 90% of use cases javascript actually makes sense and can be the most performant. This is a weird definition of performant, using more resources to achieve the same result faster, it seems akin to saying JS is more performant than C if you buy a newer CPU to run the code on. > But the more I've learnt about the benefits of "on the fly" / "just in time" optimising compilers, the more I'm convinced this is the future of computing It's been the future of computing for 30 years, possibly longer.
- swsieber 8y agoI admit the performance is improving. But it's not c level performance. Throwing multiple cores at js to get c level performance glossession over an important detail: in C, those cores are free to do other things.
- ufo 8y agoJITs aren't a panacea for everything. As the blog post said, if you want to avoid falling off a performance cliff you must write "CranskshaftScript" instead of Javascript. And the only way to be sure that the optimizer is content through a specialized profiler.