I have herd V8 compiles "hot code" optimise javascript performance. Is there any way I can tell what code has been compiled and what code has not?
First and foremost you will need to profile your code in the Profiles tab of the Javascript console in Chrome to see what is worth testing. If a function, module, or whatever you are trying to test does not take up much time, it won't be worth your effort.
V8's JIT is going to make assumptions about your code, if those assumptions are true the code will be lightning fast. If not V8 will deoptimize that code as your program continues. Here is a for instance from my own tests. In the code below I was testing a merge sort function I had written.
console.time('order');
msort(ob);
console.timeEnd('order');
The first run of 60000 random numbers completes after 8ms, and all of the following jump up to around 16ms. Basically the JIT has issues with something I wrote so it recompiled my code. I have seen the exact opposite occur where code jumps to twice as fast. If you want to look at it, this is not the exact version, but one using es6 module syntax.
https://github.com/jamesrhaley/es2015-babel-gulp-jasmine/blob/master/src/js/mergeSort/mergeSort.js
Also if your code was not worth optimizing, then it won't be optimized to begin with. Here is a couple of links that helped me improve my speed when writing js.
https://www.youtube.com/watch?v=UJPdhx5zTaw
https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#so-how-does-javascript-work-in-v8
If you are willing to build a standalone version of v8, you can just run the shell as follows: d8 --trace-opt foo.js (you might also want to deploy --trace-deopt, since your code might get deoptimized (and then reoptimized again..)).
Another useful option is --print-code which will let you see all the versions of machine code for all the functions which were compiled although this one is probably an overkill. Also there is --print-opt-code.
And lastly use d8 --help to see what other useful options v8 can take.
Related
I recently started some web development, with ASP.NET and some Javascript, and something is confusing me alot.
I always read that JavaScript used to be interpreted until JIT slowly made it so chunks are compiled to machine code (which made browsers alot faster).
This makes no sense to me. How can JavaScript compile to native machine code, if traditional JavaScript apps don't target the machine/CPU to begin with?
I understand if an electron.js app gets compiled to machine code using the NodeJS runtime. That I get. Because it natively compiles to machine code and as far as I understand it, doesn't run in a browser.
If traditional JavaScript apps run in a browser, why must it be compiled to machine code? The browser is responsible for running the code, not the CPU. The CPU runs the browser itself. I actually don't see how the native OS can influence anything that happens in the browser at all or vise versa. Seems like a security issue as well.
Sorry if it's a stupid question, but I can't find any resource that will go beyond saying "Javascript uses JIT"
Thank you!
Lauren
At the end of the day, the CPU has to run the code.
JIT-compiling it down to machine code is one way to make that faster.
How can JavaScript compile to native machine code, if traditional JavaScript apps don't target the machine/CPU to begin with?
It is not "Javascript" that is doing it, it is the browser (or rather, the Javascript execution engine inside the browser), and since it is "JIT" it knowns exactly which CPU to target (this is not done in a generic way, this is done for the specific CPU that the browser is currently running on).
So, yes, there is some mismatch, since Javascript will not use low-level primitive types that the CPU can work with directly, which is why there is a lot of indirection and speculative type inference guess-work. The resulting machine code is much different than you would get from hand-coded assembly, but it can still be a net positive. To help with this, WASM was developed, which is closer to "normal" machine code.
Other intermediate, non-CPU specific formats like JVM bytecode or CLR bytecode or LLVM bitcode are in a similar situation (in that can also be compiled to machine code they do not themselves target directly) -- but they have been "lowered" already from language source code to something close to machine code.
Seems like a security issue as well.
Yes, it can be. The browser has to be careful in what it is doing here, and the OS should sandbox the browser as much as possible.
Executing instructions is easier than running an interpreter, and JIT seeks to take advantage of this for a performance boost. All programs running on your computer become machine code at some point, the only question is which instructions are be executed.
let x=0;
for (let i=0;i<100;++i) {
x+=2;
}
Since it is clear that there are no side effects in a block of code like this, it is faster to compile instructions directly, rather than interpreting each line.
// NIOS 2 assembly, sorry its the only one i know
movi r2,0
movi r3,0
movi r4,100
loop:
addi r2,2
addi r3,1
blt r3,r4,loop
Executing this will be faster than executing the parsing logic for each individual instruction.
TLDR: All programs are always running CPU instructions, so it is faster to minimize the number of instructions by skipping the parsing stage when possible
The major JavaScript engines of web browsers and nodeJS have had just-in-time compilers for years.
I was just watching a video on Compiler Explorer showing the assembly code output by many compilers for various CPUs.
This reminded me that I've been curious about the code generated by the JS engines' jits.
Do any of those engines have ways for us to see that low-level generated code?
(If this is out of place on SO please feel free to migrate it to the correct SE site.)
For V8, there is a flag --print-opt-code, which prints generated optimized assembly code for each function that gets optimized. Note that functions only get optimized when they're "hot", not right away, so for a short "hello, world" style program the flag won't print anything. You can make functions "hot" by calling them a lot.
In older versions, there was a --print-code flag for unoptimized code, but since the baseline (non-optimizing) compiler has been replaced by an interpreter, there is no unoptimized code any more. You can print the generated bytecode with --print-bytecode.
If you're using Chrome, you can specify flags to be passed to V8 by wrapping them in --js-flags, e.g. --js-flags="--print-opt-code".
One thing you can always do is interrupt your program while it's running, using a debugger.
If it's spending most of its time in JIT-compiled code, then chances are the current instruction-pointer value (RIP) will be inside some JIT-compiled machine code, which your debugger will disassemble for you. (Or at least the part after the current RIP: x86 machine code uses variable-length instructions, so there's no reliable way to go backwards. You might single-step until you reach a backwards branch to get to the top of a loop.)
But without any way to figure out which function name you're seeing JITed asm for, this is probably not very useful unless you only have one hot loop (e.g. in an artificial test / microbenchmark).
Having the JIT engine print the asm as it generates it (#jmrk's answer) is much more usable; I only mention this technique because it works without any support from the JIT engine, so it can work on anything.
Are there any performance benefits of the latter compared to the former? When I tested it on my own, the time it took for one of my projects to load already transpiled was much shorter than when it uses babel/register. Apart from start-up time though, I'm not entirely sure what I'd write to benchmark the two fairly. Does anyone know whether the overhead Babel adds is just from babel/register transpiling code as it's running, or is it slow no matter what you do?
You are correct in that it affects startup time (it will drastically, depending on how large your project is). As for actual runtime, it should make exactly 0 difference unless there is a bug in Node itself (which would sadly not likely to be fixed, since it's deprecated).
I have a quite big JavaScript for HTML page for a device.
But it's a bit slow. I tried compressing JavaScript files but it's still not satisfactory.
So I was thinking, is it possible to make it as a Just in Time that is compiled converted to machine code and use it? (Hope my understanding is correct) I use a WebKit based browser.
Anybody please who have done this, please provide links to "How To" pages or info about the same.
Both Safari and Chrome do JIT compilation of Javascript already. In fact, the only browser in widespread use that doesn't is IE8 and earlier. This is one of the main reasons why IE8 is so much slower than the competition these days.
But reading between the lines of your question, my guess is that you're not quite understanding what JIT compilation is. JIT compilation happens on the browser; you don't need to change your code in any way at all in order for the browser to be able to do JIT compilation on it for you.
What it sounds like you're actually thinking of is bytecode compilation, such as Java does. This bytecode is effectively a half-way compiled language which is then itself JIT compiled when you run the program. If this is what you're thinking of, I can confirm that this is not an option for browser-based Javascript code.
Google have been toying with a technology called 'Native Client' (NaCl), which would allow you to provide compiled code to the browser, but this is not available yet except in development versions of Chrome.
In any case, compiling may make your code run quicker, but it wouldn't solve the fundamental issue of why it's running slowly, which is likely to be a far better thing to resolve. (even compiled code will perform badly if it has bottlenecks; compilation in itself doesn't magically make slow code better)
If you want to find out why your script is running slowly, I recommend using a profiling tool, such as the one built into Firebug or Chrome's Developer Tools. This will help you identify the parts of your code which are running slowly.
You could also try the YSlow tool, which can also give useful information on javascript performance.
You also state that you've compressed your script to try to get it to go faster. Compressing the script will help it to download quicker (because it's a smaller file), but it won't do anything for the speed that the code runs at.
Is it possible to run JavaScript code in parallel in the browser? I'm willing to sacrifice some browser support (IE, Opera, anything else) to gain some edge here.
If you don't have to manipulate the dom, you could use webworkers ... there's a few other restrictions but check it out # http://ejohn.org/blog/web-workers/
Parallel.js of parallel.js.org (see also github source) is a single file JS library that has a nice API for multithreaded processing in JavaScript. It runs both in web browsers and in Node.js.
Perhaps it would be better to recode your JavaScript in something that generally runs faster, rather than trying to speed up the Javascript by going parallel. (I expect you'll find the cost of forking parallel JavaScript activities is pretty high, too, and that may well wipe out any possible parallel gain; this is common problem with parallel programming).
Javascript is interpreted in most browsers IIRC, and it is dynamic on top of it which means it, well, runs slowly.
I'm under the impression you can write Java code and run it under browser plugins. Java is type safe and JIT compiles to machine code. I'd expect that any big computation done in Javascript would run a lot faster in Java. I'm not specifically suggesting Java; any compiled language for which you can get a plug in would do.
As an alternative, Google provides Closure, a JavaScript compiler. It is claimed to be a compiler, but looks like an optimizer to me and I don't know much it "optimizes". But, perhaps you can use that. I'd expect the Closure compiler to be built into Chrome (but I don't know for a fact) and maybe just running Chrome would get your JavaScript compiler "for free".
EDIT: After reading about what about Closure does, as compiler guy I'm not much impressed. It looks like much of the emphasis is on reducing code size which minimizes download time but not necessarily performance. The one good thing they do in function inlining. I doubt that will help as much as switching to a truly compiled langauge.
EDIT2: Apparantly the "Closure" compiler is different than the engine than runs JavaScript in Chrome. I'm told, but don't know this for a fact, that the Chrome engine has a real compiler.
Intel is coming up with an open-source project codenamed River Trail check out http://www.theregister.co.uk/2011/09/17/intel_parallel_javascript/