Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[TDCSP 2016 - Node] Deixando o V8 otimizar sua ...

[TDCSP 2016 - Node] Deixando o V8 otimizar sua aplicação Node

Aprenda a trabalhar com o compilador JIT do V8, o Crankshaft, pra deixar sua aplicação Node bem mais rápida!

More Decks by Talysson de Oliveira Cassiano

Other Decks in Programming

Transcript

  1. V8 & Crankshaft Full compiler Crankshaft compiler AST CPU JS

    Código nativo otimizado Código nativo Código otimizável
  2. V8 & Crankshaft Full compiler Crankshaft compiler AST Código nativo

    CPU JS Bail out Código otimizável Código nativo otimizado
  3. function myFastFunction(a, _b) { var b = _b; if(arguments.length <

    2) { b = 5; } } 1) Atribuição em argumento function mySlowFunction(a, b) { if(arguments.length < 2) { b = 5; } }
  4. var args = new Array(arguments.length); for(var i = 0; i

    < args.length; ++i) { args[i] = arguments[i]; } * Uso seguro do arguments arguments.length; arguments[i]; // `i` válido fn.apply(y, arguments); // único
  5. 3) For-in em objetos em hash table mode var hashTable

    = { 'invalid-identifier': 3, 123: 'not cool' validIdentifier: 'cool' }; delete hashTable.validIdentifier; for(var key in hashTable) { console.log('I am slow!'); }
  6. var hashTable = { 'invalid-identifier': 3, validIdentifier: 'cool' }; delete

    hashTable.validIdentifier; var keys = Object.keys(hashTable); keys.forEach(function(key) { console.log('I am fast!!'); }); 3) For-in em objetos em hash table mode var hashTable = { 'invalid-identifier': 3, 123: 'not cool' validIdentifier: 'cool' }; delete hashTable.validIdentifier; for(var key in hashTable) { console.log('I am slow!'); }
  7. var key; function nonLocalKey2() { var obj = {}; for(key

    in obj); } function nonLocalKey1() { var obj = {}; for(var key in obj); return function() { return key; }; } 4) For-in com chave não local
  8. var array = [1, 2, 3]; for(var i in array)

    { console.log(array[i]); } 5) For-in em objetos com índices numéricos
  9. var array = [1, 2, 3]; for(var i in array)

    { console.log(array[i]); } 5) For-in em objetos com índices numéricos var array = [1, 2, 3]; var length = array.length; for(var i = 0; i < length; i++) { console.log(array[i]); } array.forEach((v) => { console.log(v); });
  10. 6) try/catch e try/finally function slowTryCatch() { try { for(var

    i = 0; i++; i < 1000) { console.log(i * i * i); } } catch(e) { console.log(e); } }
  11. function fastTryCatch() { try { doSomethingHeavy(); } catch(e) { console.log(e);

    } } 6) try/catch e try/finally function slowTryCatch() { try { for(var i = 0; i++; i < 1000) { console.log(i * i * i); } } catch(e) { console.log(e); } }
  12. 7) Parâmetro de tipo não esperado var obj = {

    prop1: 1 }; function test(param) { param.prop2 = 2; // não tem `prop2` } test(obj);
  13. var obj = { prop1: 1, prop2: null }; function

    test(param) { param.prop2 = 2; // tem `prop2` } test(obj); 7) Parâmetro de tipo não esperado var obj = { prop1: 1 }; function test(param) { param.prop2 = 2; // não tem `prop2` } test(obj);
  14. 8) Funções com argumentos variáveis function calc() { if(arguments.length ===

    2) { return arguments[0] * arguments[1]; } return arguments[0]; }
  15. function calc() { if(arguments.length === 2) { return calcTwo(arguments[0], arguments[1]);

    } return calcOne(arguments[0]); } function calcOne(a) { return a } function calcTwo(a, b) { return a * b } 8) Funções com argumentos variáveis function calc() { if(arguments.length === 2) { return arguments[0] * arguments[1]; } return arguments[0]; }
  16. 9) Uso de debugger function fnWithDebugger() { if(process.env.NODE_ENV === 'dev')

    { debugger; } } function fnWithDebugger() { if(false) { debugger; } }
  17. function fnWithEval(param) { return; eval(`this.alert(${param})`); } 10) Uso de eval()

    function fnWithEval(param) { eval(`this.alert(${param})`); }
  18. function * generator1(param) { var something = 0; for(var i

    = 0; i < 1000; i++) { something += i; } yield something; } 11) Generators function * generator2(param) { for(var i = 0; i < 1000; i++) { yield i; } }
  19. for(var item of array) { console.log(item); } 12) Uso de

    for-of var length = array.length; for(var i = 0; i < length; i++) { console.log(array[i]); } array.forEach((item) => { console.log(item); });
  20. Entre outros • Objetos com __proto__ • Objetos com set

    / get • Funções muito grandes • Uso do with • Índice negativo em arrays • Nome de propriedade computada • Otimização falhou muitas vezes • Uso do super • ...
  21. TurboFan • Novo JIT do V8 • Trabalha após o

    Crankshaft • Otimizações mais sofisticadas • Eventualmente substituirá o Crankshaft TurboFan no Chrome 41
  22. Referências • Optimization killers: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers • V8 bailout reasons: https://github.com/vhf/v8-bailout-reasons

    • NodeJS Anti-Patterns: https://github.com/zhangchiqing/OptimizationKillers • A tour of V8: Crankshaft, the optimizing compiler: http://jayconrod.com/posts/54/a-tour- of-v8-crankshaft-the-optimizing-compiler • Bailout reasons: https://cs.chromium.org/chromium/src/v8/src/bailout-reason.h • TurboFan: http://v8project.blogspot.com.br/2015/07/digging-into-turbofan-jit.html • TurboFan performance: http://blog.chromium.org/2015/07/revving-up-javascript- performance-with.html