105
Extreme JavaScript Performance Thomas Fuchs @thomasfuchs

Extreme JavaScript Performance

Embed Size (px)

DESCRIPTION

Talk given at http://jsconf.eu 2009. You serve up your code gzipped. Your caches are properly configured. Your data (and scripts) are loaded on-demand. That's awesome—so don't stop there. Runtime is another source of slowdowns, and you can learn to conquer those, too. Learn how to benchmark your code to isolate performance issues, and what to do when you find them. The techniques you'll learn range from the normal (function inlining) to the extreme (unrolling loops).

Citation preview

Page 1: Extreme JavaScript Performance

Extreme JavaScript

Performance

Thomas Fuchs@thomasfuchs

Page 2: Extreme JavaScript Performance
Page 3: Extreme JavaScript Performance

DO NOT, EVER,OPTIMIZE

PREMATURELY

Page 4: Extreme JavaScript Performance

http://tr.im/extremejs

Page 5: Extreme JavaScript Performance
Page 6: Extreme JavaScript Performance

SpiderMonkey

Page 7: Extreme JavaScript Performance

SpiderMonkey

JavaScriptCore

Page 8: Extreme JavaScript Performance

SpiderMonkey

JavaScriptCore

JScript

Page 9: Extreme JavaScript Performance

SpiderMonkey

JavaScriptCore

JScript

V8

Page 10: Extreme JavaScript Performance

#1 avoid function calls

Page 11: Extreme JavaScript Performance

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;}

Page 12: Extreme JavaScript Performance

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;}

Page 13: Extreme JavaScript Performance

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;}

Page 14: Extreme JavaScript Performance

methodCall() inlinedMethod()

0.410s 0.150s

0.056s 0.045s

uhm,  hmm† 0.128s

0.027s 0.016s

Page 15: Extreme JavaScript Performance

methodCall() inlinedMethod()

0.410s 0.150s

0.056s 0.045s

uhm,  hmm† 0.128s

0.027s 0.016s

Page 16: Extreme JavaScript Performance

methodCall() inlinedMethod()

0.410s 0.150s

0.056s 0.045s

uhm,  hmm† 0.128s

0.027s 0.016s

Page 17: Extreme JavaScript Performance

methodCall() inlinedMethod()

0.410s 0.150s

0.056s 0.045s

uhm,  hmm† 0.128s

0.027s 0.016s

Page 18: Extreme JavaScript Performance

methodCall() inlinedMethod()

0.410s 0.150s

0.056s 0.045s

uhm,  hmm† 0.128s

0.027s 0.016s

Page 19: Extreme JavaScript Performance

IE8 throws this warning after 1 second

Page 20: Extreme JavaScript Performance

#2 embrace the

language

Page 21: Extreme JavaScript Performance

function  literals(){    var  a  =  [],  o  =  {};}

function  classic(){    var  a  =  new  Array,  o  =  new  Object;}

Page 22: Extreme JavaScript Performance

classic() literals()

0.291s 0.265s

0.020s 0.016s

0.220s 0.185s

0.024s 0.010s

Page 23: Extreme JavaScript Performance

classic() literals()

0.291s 0.265s

0.020s 0.016s

0.220s 0.185s

0.024s 0.010s

Page 24: Extreme JavaScript Performance

classic() literals()

0.291s 0.265s

0.020s 0.016s

0.220s 0.185s

0.024s 0.010s

Page 25: Extreme JavaScript Performance

classic() literals()

0.291s 0.265s

0.020s 0.016s

0.220s 0.185s

0.024s 0.010s

Page 26: Extreme JavaScript Performance

classic() literals()

0.291s 0.265s

0.020s 0.016s

0.220s 0.185s

0.024s 0.010s

Page 27: Extreme JavaScript Performance

>  parseInt(12.5);12

Page 28: Extreme JavaScript Performance

>  ~~(1  *  "12.5")12

Page 29: Extreme JavaScript Performance

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

Page 30: Extreme JavaScript Performance

parseInt() weird  stuff

0.003s 0.002s

0.088s 0.081s

uhm,  hmm† 0.547s

0.109s 0.282s

Page 31: Extreme JavaScript Performance

parseInt() weird  stuff

0.003s 0.002s

0.088s 0.081s

uhm,  hmm† 0.547s

0.109s 0.282s

Page 32: Extreme JavaScript Performance

parseInt() weird  stuff

0.003s 0.002s

0.088s 0.081s

uhm,  hmm† 0.547s

0.109s 0.282s

Page 33: Extreme JavaScript Performance

parseInt() weird  stuff

0.003s 0.002s

0.088s 0.081s

uhm,  hmm† 0.547s

0.109s 0.282s

Page 34: Extreme JavaScript Performance

parseInt() weird  stuff

0.003s 0.002s

0.088s 0.081s

uhm,  hmm† 0.547s

0.109s 0.282s

Page 35: Extreme JavaScript Performance

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

Page 36: Extreme JavaScript Performance

#3 loops

Page 37: Extreme JavaScript Performance

var  test  =  '';for  (var  i  =  0;i<10000;i++)  test  =  test  +  str;

var  test  =  '',  i  =  10000;while(i-­‐-­‐)  test  =  test  +  str;

Page 38: Extreme JavaScript Performance

for  loop while  loop

0.12s 0.12s

0.13s 0.13s

0.6s 0.6s

0.04s 0.04s

Page 39: Extreme JavaScript Performance

for  loop while  loop

0.12s 0.12s

0.13s 0.13s

0.6s 0.6s

0.04s 0.04s

Page 40: Extreme JavaScript Performance

for  loop while  loop

0.12s 0.12s

0.13s 0.13s

0.6s 0.6s

0.04s 0.04s

Page 41: Extreme JavaScript Performance

for  loop while  loop

0.12s 0.12s

0.13s 0.13s

0.6s 0.6s

0.04s 0.04s

Page 42: Extreme JavaScript Performance

for  loop while  loop

0.12s 0.12s

0.13s 0.13s

0.6s 0.6s

0.04s 0.04s

Page 43: Extreme JavaScript Performance

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)

Page 44: Extreme JavaScript Performance

function  normalLoop(){    var  i=60,  j=0;    while(i-­‐-­‐)  j++;}

Page 45: Extreme JavaScript Performance

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++;}

Page 46: Extreme JavaScript Performance

normalLoop() unrolledLoop()

0.023s 0.010s

0.003s 0.001s

0.032s 0.015s

0.005s 0.001s

Page 47: Extreme JavaScript Performance

normalLoop() unrolledLoop()

0.023s 0.010s

0.003s 0.001s

0.032s 0.015s

0.005s 0.001s

Page 48: Extreme JavaScript Performance

normalLoop() unrolledLoop()

0.023s 0.010s

0.003s 0.001s

0.032s 0.015s

0.005s 0.001s

Page 49: Extreme JavaScript Performance

normalLoop() unrolledLoop()

0.023s 0.010s

0.003s 0.001s

0.032s 0.015s

0.005s 0.001s

Page 50: Extreme JavaScript Performance

normalLoop() unrolledLoop()

0.023s 0.010s

0.003s 0.001s

0.032s 0.015s

0.005s 0.001s

Page 51: Extreme JavaScript Performance

#4 cache globals

Page 52: Extreme JavaScript Performance

function  uncached(){    var  i  =  10000;    while(i-­‐-­‐)  window.test  =  'test';}

function  cached(){    var  w  =  window,  i  =  10000;    while(i-­‐-­‐)  w.test  =  'test';}

Page 53: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Page 54: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Page 55: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Page 56: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Page 57: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Page 58: Extreme JavaScript Performance

uncached cached

1.440s 0.825s

0.07s 0.07s

2.22s 2.19s

0.48s 0.16s

Safari is 20x fasterthan Firefox

Page 59: Extreme JavaScript Performance

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?

Page 60: Extreme JavaScript Performance

#5 expression tuning

Page 61: Extreme JavaScript Performance

var  b  =  false,  n  =  99;

function(){    return  n*n  &&  b;}

function(){    return  b  &&  n*n;}

Page 62: Extreme JavaScript Performance

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

Page 63: Extreme JavaScript Performance

not  tuned tuned

0.005s 0.004s

0.011s 0.010s

0.906s 0.391s

0.037s 0.021s

Page 64: Extreme JavaScript Performance

not  tuned tuned

0.005s 0.004s

0.011s 0.010s

0.906s 0.391s

0.037s 0.021s

Page 65: Extreme JavaScript Performance

not  tuned tuned

0.005s 0.004s

0.011s 0.010s

0.906s 0.391s

0.037s 0.021s

Page 66: Extreme JavaScript Performance

not  tuned tuned

0.005s 0.004s

0.011s 0.010s

0.906s 0.391s

0.037s 0.021s

Page 67: Extreme JavaScript Performance

not  tuned tuned

0.005s 0.004s

0.011s 0.010s

0.906s 0.391s

0.037s 0.021s

Page 68: Extreme JavaScript Performance

>>>  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

Page 69: Extreme JavaScript Performance

#6what not to use

Page 70: Extreme JavaScript Performance

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;}

Page 71: Extreme JavaScript Performance

with(obj){  p  } obj.p

0.071s 0.012s

0.039s 0.028s

0.078s 0.078s

0.077s 0.006s

Page 72: Extreme JavaScript Performance

with(obj){  p  } obj.p

0.071s 0.012s

0.039s 0.028s

0.078s 0.078s

0.077s 0.006s

Page 73: Extreme JavaScript Performance

with(obj){  p  } obj.p

0.071s 0.012s

0.039s 0.028s

0.078s 0.078s

0.077s 0.006s

Page 74: Extreme JavaScript Performance

with(obj){  p  } obj.p

0.071s 0.012s

0.039s 0.028s

0.078s 0.078s

0.077s 0.006s

Page 75: Extreme JavaScript Performance

with(obj){  p  } obj.p

0.071s 0.012s

0.039s 0.028s

0.078s 0.078s

0.077s 0.006s

Page 76: Extreme JavaScript Performance

var  a  =  0;

function(){    try{        a  +=  1;    }  catch(e)  {}}

function(){    a  +=  1;}

Page 77: Extreme JavaScript Performance

try/catch no  try/catch

0.006s 0.005s

0.287s 0.011s

0.460s 0.460s

0.123s 0.012s

Page 78: Extreme JavaScript Performance

try/catch no  try/catch

0.006s 0.005s

0.287s 0.011s

0.460s 0.460s

0.123s 0.012s

Page 79: Extreme JavaScript Performance

try/catch no  try/catch

0.006s 0.005s

0.287s 0.011s

0.460s 0.460s

0.123s 0.012s

Page 80: Extreme JavaScript Performance

try/catch no  try/catch

0.006s 0.005s

0.287s 0.011s

0.460s 0.460s

0.123s 0.012s

Page 81: Extreme JavaScript Performance

try/catch no  try/catch

0.006s 0.005s

0.287s 0.011s

0.460s 0.460s

0.123s 0.012s

Page 82: Extreme JavaScript Performance

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

Page 83: Extreme JavaScript Performance

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

Page 84: Extreme JavaScript Performance

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

Page 85: Extreme JavaScript Performance

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

Page 86: Extreme JavaScript Performance

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

Page 87: Extreme JavaScript Performance

Modern JavaScript engines have JIT

compilers, which don’t support certain

features well

Page 88: Extreme JavaScript Performance
Page 89: Extreme JavaScript Performance
Page 90: Extreme JavaScript Performance

Avoid stuffthat’s not

available inECMA-2625th Edition

“strict” mode,see John’s blog

post

Page 91: Extreme JavaScript Performance

Avoid stuffthat’s not

available inECMA-2625th Edition

“strict” mode,see John’s blog

post

http://tr.im/ecma262

Page 92: Extreme JavaScript Performance

alert((function(){return"alert(("+arguments.callee.toString().replace(/\s/g,"")+")());";})());

Page 93: Extreme JavaScript Performance

alert((function(){return"alert(("+arguments.callee.toString().replace(/\s/g,"")+")());";})());

Page 94: Extreme JavaScript Performance

(function(){  return  2  *  3;  }).toString();

Page 95: Extreme JavaScript Performance
Page 96: Extreme JavaScript Performance

function  ()  {  return  2  *  3;  }

Page 97: Extreme JavaScript Performance

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

Page 98: Extreme JavaScript Performance

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

Page 99: Extreme JavaScript Performance

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

function  ()  {  return  6;  }

Page 100: Extreme JavaScript Performance

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

function  ()  {  return  2  *  3;  }

function  ()  {  return  6;  } WTF?

Page 101: Extreme JavaScript Performance

More inhttp://jsrocks.com

Page 102: Extreme JavaScript Performance

More inhttp://jsrocks.com

Page 103: Extreme JavaScript Performance
Page 104: Extreme JavaScript Performance

DO NOT, EVER,OPTIMIZE

PREMATURELY

Page 105: Extreme JavaScript Performance

Q&AAnd thanks!

http://javascriptrocks.com/@thomasfuchs on twitter