tdc2016sp - trilha node.js

35
Deixando o V8 otimizar sua aplicação Node

Upload: tdc-globalcode

Post on 13-Apr-2017

140 views

Category:

Education


1 download

TRANSCRIPT

Page 1: TDC2016SP - Trilha Node.Js

Deixando o V8 otimizar sua aplicação Node

Page 2: TDC2016SP - Trilha Node.Js

Talysson / @talyssonoctalyssonoc.github.io Codeminer42

Page 3: TDC2016SP - Trilha Node.Js

Node & V8

Page 4: TDC2016SP - Trilha Node.Js

Node & V8

● V8: máquina virtual JS● Libuv: async I/O

+

=

Page 5: TDC2016SP - Trilha Node.Js

V8 & Crankshaft

Fullcompiler

AST Código nativo

CPUJS

Page 6: TDC2016SP - Trilha Node.Js

V8 & Crankshaft

Fullcompiler

Crankshaftcompiler

AST

CPUJS

Códigonativo

otimizado

Código nativo

Código otimizável

Page 7: TDC2016SP - Trilha Node.Js

V8 & Crankshaft

Fullcompiler

Crankshaftcompiler

AST

Código nativo

CPUJS

Bail out

Código otimizável Códigonativo

otimizado

Page 8: TDC2016SP - Trilha Node.Js

Escrevendo código otimizável

Page 9: TDC2016SP - Trilha Node.Js

1) Atribuição em argumento

function mySlowFunction(a, b) {

if(arguments.length < 2) {

b = 5;

}

}

Page 10: TDC2016SP - Trilha Node.Js

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;

}

}

Page 11: TDC2016SP - Trilha Node.Js

var args = [].slice.call(arguments);

2) Vazamento do arguments

function leaksArguments() {

return arguments;

}

Page 12: TDC2016SP - Trilha Node.Js

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

Page 13: TDC2016SP - Trilha Node.Js

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!');

}

Page 14: TDC2016SP - Trilha Node.Js

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!');

}

Page 15: TDC2016SP - Trilha Node.Js

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

Page 16: TDC2016SP - Trilha Node.Js

var array = [1, 2, 3];

for(var i in array) {

console.log(array[i]);

}

5) For-in em objetos com índices numéricos

Page 17: TDC2016SP - Trilha Node.Js

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

});

Page 18: TDC2016SP - Trilha Node.Js

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

}

}

Page 19: TDC2016SP - Trilha Node.Js

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

}

}

Page 20: TDC2016SP - Trilha Node.Js

7) Parâmetro de tipo não esperado

var obj = { prop1: 1 };

function test(param) {

param.prop2 = 2; // não tem `prop2`

}

test(obj);

Page 21: TDC2016SP - Trilha Node.Js

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

Page 22: TDC2016SP - Trilha Node.Js

8) Funções com argumentos variáveis

function calc() {

if(arguments.length === 2) {

return arguments[0] * arguments[1];

}

return arguments[0];

}

Page 23: TDC2016SP - Trilha Node.Js

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

}

Page 24: TDC2016SP - Trilha Node.Js

9) Uso de debugger

function fnWithDebugger() {

if(process.env.NODE_ENV === 'dev') {

debugger;

}

}

function fnWithDebugger() {

if(false) {

debugger;

}

}

Page 25: TDC2016SP - Trilha Node.Js

function fnWithEval(param) {

return;

eval(`this.alert(${param})`);

}

10) Uso de eval()

function fnWithEval(param) {

eval(`this.alert(${param})`);

}

Page 26: TDC2016SP - Trilha Node.Js

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;

}

}

Page 27: TDC2016SP - Trilha Node.Js

for(var item of array) {

console.log(item);

}

12) Uso de for-of

Page 28: TDC2016SP - Trilha Node.Js

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

});

Page 29: TDC2016SP - Trilha Node.Js

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

Page 30: TDC2016SP - Trilha Node.Js

Mas isso funciona mesmo?!

Page 31: TDC2016SP - Trilha Node.Js

Exemplos de resultados

Bluebird

EventEmitter2

Page 32: TDC2016SP - Trilha Node.Js

O futuro do V8: TurboFan

Page 33: TDC2016SP - Trilha Node.Js

TurboFan

● Novo JIT do V8● Trabalha após o

Crankshaft● Otimizações mais

sofisticadas● Eventualmente

substituirá o Crankshaft

TurboFan no Chrome 41

Page 34: TDC2016SP - Trilha Node.Js

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

Page 35: TDC2016SP - Trilha Node.Js

Talysson / @talyssonoctalyssonoc.github.io