No - I have run tests and seen the results for myself. The arrangement of the code in JavaScript can make a difference to execution times where it shouldn't make a difference if the code were to be compiled.
Such differences are so small though that the most important part of how you write your code most of the time will be maintainability rather than execution time.
Do you happen to have those tests available somewhere? I just wrote a quick test myself and at least the V8 engine doesn't show any mentionable difference between inlining and extraction.
Glad to see that we can agree on readability and maintainability being more important than fractions of milliseconds, though.
But that is only true "in theory". In reality, engines like V8 do compile JavaScript and they do a lot of optimization. Simply because JavaScript is an old language that gained so much popularity that it needs to run faster and faster.
That’s called Just In Time (JIT) Compilation and every JS engine I know does it.
__________________
please post your code wrapped in [CODE] [/CODE] tags
That’s called Just In Time (JIT) Compilation and every JS engine I know does it.
If JavaScript is actually doing that now then why is it that if your code contains a syntax error you can still have it run up to the point where the error is rather than having the error reported by the compile step the way the JIT compiler does in PHP?
Or is it just so long since I last had a syntax error that I haven't noticed the change in the way it works?
when it is compiled just in time, well, it is compiled just before the code is run, not when all is loaded.
When it "compiles" each statement as it gets to it then what you have is called an interpreter. Scripting languages have almost always worked that way.
PHP uses a JIT compiler - it compiles the entire code before it starts to run any of it. So you get PHP syntax errors before any of the code runs.
Compiling is a once per page process - a JIT JavaScript compiler would have to wait until the page finished loading in order to get all the JavaScript to be compiled. That it runs once per page and not once per statement is the difference between a JIT compiler and an interpteter. I suppose they might have made the JavaScript interpreter more efficient by having it look at larger blocks of code at once rather than individual statements - that would allow it to "compile" an entire loop once before running it rather than each statement every time it runs. It still doesn't make it a compiler though as with a compiler if you capture the output then the page can be loaded and run as often as you like without needing the original language or compiler at all.
the JS engine(er)s call it JIT compiler, how compareable that is to a "real" compiler is a completely different question (and I don’t want to discuss that here).
__________________
please post your code wrapped in [CODE] [/CODE] tags
If JavaScript is actually doing that now then why is it that if your code contains a syntax error you can still have it run up to the point where the error is rather than having the error reported by the compile step the way the JIT compiler does in PHP?
Or is it just so long since I last had a syntax error that I haven't noticed the change in the way it works?
no, a syntax error will show itself upon parsing, unless you use eval to hide it.
its reference errors that can show up at runtime...
js engines load all the scripts at once, then parse them one at a time.
V8 executes js in assembly code, which is generated for the V8 VM by it's JIT engine.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
Yeah, even way back in MSIE 4, the JScript engine was actually a semi-JIT compiler.
It didn't do any optimization, to speak of, but it did convert the JS source code to an intermediate "byte code" form and then "interpreted" the byte code. (Which really means it just picked up a token and looked up the address of the code to execute that token in a translation table.) (And I know all this because we--75% I--converted Microsoft's source code to run on an IBM mainframe in 1998.)
Heck, all the BASIC interpreters that I wrote (or helped write) did that same thing, as far back as 1977. I even wrote an article on how we did it for Infoworld, back in 1978 (maybe early 1979). And then we published a book on how we did it for Atari BASIC in...ummm...1983 I think. Maybe 1982. It's really not hard, and it improves performance of some operations by an order of magnitude or more.
Now, the OPTIMIZATION of such code is much harder. Did a little bit of that in 1984 through 1987, but nothing like I'm sure modern JS engines do.
I did help work on a combined Java/C++ compiler, though, that could JIT code blocks as small as a single function. That was 1993-1997. I don't know why the same techniques couldn't be applied to JavaScript, though there are a few unique problems in JS that don't exist in strongly-typed languages.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
js engines load all the scripts at once, then parse them one at a time.
How can it do that if some of the scripts are actually loaded from within the code itself.
One reason why you can't have a full JIT compiler for Javascript and would at most be able to compile individual functions is code like:
Code:
a = function(nm) {
var s = document.createElement('script');
s.type='text/javascript';
s.src=nm;
document.getElementsByTagName('body')[0].appendChild(s);
}
a('firstscript.js');
a('secondscript.js');
If it waits until all the scripts load before it even starts to compile then it can never start because until that first function is run twice you don't have all the code loaded.
The other consideration regarding compolied code is that if you SAVE the output from the compile step then you can run it again without having to recompile it. Tf you can't actually save the output to rerun then no matter what it is called it is little more than an interpreter.
Basically modern browsers (including IE4) have made the JavaScript interpreter more efficient by using intermediate languages and temporarily storing that to rerun if it is called from the same page. It isn't really compiled because you can't rerun it next week without having to go through it all again.
One of the latest JIT compiler for PHP stores the compiled version in a database and serves it from there when available instead of recompiling it for every visitor. Even the original one lists the syntax errors in the whole page before running any of the code. PHP is as loosely typed as JavaScript so that isn't what is stopping a proper JavaScript compiler from being developed. It is that the script runs in the browser often before the page finishes loading that presents the biggest problem to compiling JavaScript - in some cases the script has finished and requested a new page before the page has even started to load any of the body.
from what i understand (not a old-school code expert):
chakra and v8 both download all the scripts right away and start execution using an interpreter. outside of the stack, the other resources are compiled to bytecode in the background. In chakra, this happens on a secondary CPU. Once the compilation is done, the interpreter hands the stack over to the compiled code.
loading a new script simply adds more symbols into the table. Since you're already active when that newly-added external script is fetched, it can be interpreted as soon as it arrives, if need be. The file's code will work using both interpretation and JIT bytecode, and interchangeably between different combos of the two.
V8 goes a little further, converting many structures (arr/obj) to fast C-style low-level code, strongly typed. If you have an array of integers, they are stored as an array of shorts. if you then push 0.5 onto that array, the whole array must be re-calc'd using the medium-speed bytecode to produce a mixed array of shorts and one float. That slows things down, so it's good to pretend JS is strongly-typed for best performance. Provided you don't mix types or introduce extra closures, the low-level V8 code executes at roughly 85% the speed of C++.
the JIT overhead is almost negligible. V8 and chakra both digest about 10MB/s of JS code, so jQuery only adds 2ms to boot times, and only the first time. Chakra can parse even faster than V8 given its idle-CPU JIT engine, but both cache their inputs based on URL and http conventions, so a page reload won't destroy that bytecoded version of jQuery.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
One of the latest JIT compiler for PHP stores the compiled version in a database and serves it from there when available instead of recompiling it for every visitor.
That's actually kind of funny.
The very first versions of Microsoft JScript and VBScript did the same thing!
Well, almost. Instead, they maintained an IN-MEMORY cache of compiled scripts. So each new visitor *could* get the pre-compiled form. Only if the cache got full did they start tossing out old compilations on a least-recently-used basis. (Hey, disk drives were a lot slower, then. So in-memory was a huge advantage.)
Of course, in the early days of those languages, a typical computer had maybe 16MB of memory, so the caches weren't very big. But by the time we were using 256MB machines, many sites could run for days without ever tossing anything out of the cache.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Those are pretty impressive stats, RndMe. But it just proves what I have contended for a long time: It *can* be done. It's just a matter of the developers wanting to spend the effort to do it.
And thank for the info about the advantages of pretending JS is strongly typed. I was wondering how JS could achieve the kind of JIT performance we did with Java and C++ (almost 20 years ago! what took JS so long?), and that's a great explanation. Makes tons of sense.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Those are pretty impressive stats, RndMe. But it just proves what I have contended for a long time: It *can* be done. It's just a matter of the developers wanting to spend the effort to do it.
And thank for the info about the advantages of pretending JS is strongly typed. I was wondering how JS could achieve the kind of JIT performance we did with Java and C++ (almost 20 years ago! what took JS so long?), and that's a great explanation. Makes tons of sense.
for an informative video on V8 in particular, and how you can profile and view the "compiled" code internally produced from your JS, checkout this google IO presentation from last summer. it's not the most exciting, but redeems itself in the last 20 mins or so.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
V8 goes a little further, converting many structures (arr/obj) to fast C-style low-level code, strongly typed. If you have an array of integers, they are stored as an array of shorts. if you then push 0.5 onto that array, the whole array must be re-calc'd using the medium-speed bytecode to produce a mixed array of shorts and one float. That slows things down, so it's good to pretend JS is strongly-typed for best performance. Provided you don't mix types or introduce extra closures, the low-level V8 code executes at roughly 85% the speed of C++.
That is really useful information. Another thing to keep in mind when writing JavaScript when it comes to efficient execution.
It gives one further reason for writing JavaScript as if it were strongly typed to go with the benefits that writing the code that way already provided.