Extreme JavaScript Performance
-
Upload
thomas-fuchs -
Category
Technology
-
view
74.596 -
download
1
description
Transcript of Extreme JavaScript Performance
Extreme JavaScript
Performance
Thomas Fuchs@thomasfuchs
DO NOT, EVER,OPTIMIZE
PREMATURELY
SpiderMonkey
SpiderMonkey
JavaScriptCore
SpiderMonkey
JavaScriptCore
JScript
SpiderMonkey
JavaScriptCore
JScript
V8
#1 avoid function calls
function methodCall(){ function square(n){ return n*n }; var i=10000, sum = 0; while(i-‐-‐) sum += square(i);}
function inlinedMethod(){ var i=10000, sum = 0; while(i-‐-‐) sum += i*i;}
function methodCall(){ function square(n){ return n*n }; var i=10000, sum = 0; while(i-‐-‐) sum += square(i);}
function inlinedMethod(){ var i=10000, sum = 0; while(i-‐-‐) sum += i*i;}
function methodCall(){ function square(n){ return n*n }; var i=10000, sum = 0; while(i-‐-‐) sum += square(i);}
function inlinedMethod(){ var i=10000, sum = 0; while(i-‐-‐) sum += i*i;}
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm, hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm, hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm, hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm, hmm† 0.128s
0.027s 0.016s
methodCall() inlinedMethod()
0.410s 0.150s
0.056s 0.045s
uhm, hmm† 0.128s
0.027s 0.016s
IE8 throws this warning after 1 second
#2 embrace the
language
function literals(){ var a = [], o = {};}
function classic(){ var a = new Array, o = new Object;}
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
classic() literals()
0.291s 0.265s
0.020s 0.016s
0.220s 0.185s
0.024s 0.010s
> parseInt(12.5);12
> ~~(1 * "12.5")12
1 * string coerces thestring into a float,
result = 12.5
double bitwise NOT*floors the number
> ~~(1 * "12.5")12
*good overview on http://tr.im/bitwise
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
parseInt() weird stuff
0.003s 0.002s
0.088s 0.081s
uhm, hmm† 0.547s
0.109s 0.282s
Firefox is 30x faster than Safari
#3 loops
var test = '';for (var i = 0;i<10000;i++) test = test + str;
var test = '', i = 10000;while(i-‐-‐) test = test + str;
for loop while loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for loop while loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for loop while loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for loop while loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
for loop while loop
0.12s 0.12s
0.13s 0.13s
0.6s 0.6s
0.04s 0.04s
var test = '';for (var i = 0;i<10000;i++) test = test + str;
var test = '', i = 10000;while(i-‐-‐) test = test + str;
3 expressions in “for”
1 expression in “while”(when i equals 0, expression will be false)
function normalLoop(){ var i=60, j=0; while(i-‐-‐) j++;}
function unrolledLoop(){ var j=0; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++; j++;}
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
normalLoop() unrolledLoop()
0.023s 0.010s
0.003s 0.001s
0.032s 0.015s
0.005s 0.001s
#4 cache globals
function uncached(){ var i = 10000; while(i-‐-‐) window.test = 'test';}
function cached(){ var w = window, i = 10000; while(i-‐-‐) w.test = 'test';}
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
Safari is 20x fasterthan Firefox
uncached cached
1.440s 0.825s
0.07s 0.07s
2.22s 2.19s
0.48s 0.16s
Now IE works with >1s durations. WTF?
#5 expression tuning
var b = false, n = 99;
function(){ return n*n && b;}
function(){ return b && n*n;}
var b = false, n = 99;
function(){ return n*n && b;}
function(){ return b && n*n;} b is false,
so n*n doesn’t needto get evaluated
not tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
not tuned tuned
0.005s 0.004s
0.011s 0.010s
0.906s 0.391s
0.037s 0.021s
>>> var n = 1;undefined>>> if(true && (n=2)) ...;>>> n2>>> if(true || (n=3)) ...;>>> n2
not a pure engine optimization,the execution actually stops
here, n=2 needs to be evaluated, so n is set to 2
here it doesn’t (expression must be true), so n is
NOT set to 3
#6what not to use
function(){ var obj = { prop: 'test', str: '' }; with(obj){ var i = 10000; while(i-‐-‐) str += prop; return str; }}
function(){ var obj = { prop: 'test', str: '' }, i = 10000; while(i-‐-‐) obj.str += obj.prop; return obj.str;}
with(obj){ p } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){ p } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){ p } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){ p } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
with(obj){ p } obj.p
0.071s 0.012s
0.039s 0.028s
0.078s 0.078s
0.077s 0.006s
var a = 0;
function(){ try{ a += 1; } catch(e) {}}
function(){ a += 1;}
try/catch no try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
try/catch no try/catch
0.006s 0.005s
0.287s 0.011s
0.460s 0.460s
0.123s 0.012s
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Firefox 3.5
Safari 4.0
Chrome 3
IE 8
0 0,1 0,2 0,3 0,4 0,5
no try/catch try/catch
Modern JavaScript engines have JIT
compilers, which don’t support certain
features well
Avoid stuffthat’s not
available inECMA-2625th Edition
“strict” mode,see John’s blog
post
Avoid stuffthat’s not
available inECMA-2625th Edition
“strict” mode,see John’s blog
post
http://tr.im/ecma262
alert((function(){return"alert(("+arguments.callee.toString().replace(/\s/g,"")+")());";})());
alert((function(){return"alert(("+arguments.callee.toString().replace(/\s/g,"")+")());";})());
(function(){ return 2 * 3; }).toString();
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 6; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 2 * 3; }
function () { return 6; } WTF?
DO NOT, EVER,OPTIMIZE
PREMATURELY
Q&AAnd thanks!
http://javascriptrocks.com/@thomasfuchs on twitter