O documento discute como otimizar aplicações Node para o motor V8. Ele explica como o V8 compila código JavaScript para código de máquina nativo e como o Crankshaft e o TurboFan otimizam esse processo. O documento também lista 12 técnicas que podem prejudicar a otimização, como atribuições em argumentos, vazamentos do arguments e uso de for-in em objetos.
9. 1) Atribuição em argumento
function mySlowFunction(a, b) {
if(arguments.length < 2) {
b = 5;
}
}
10. 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;
}
}
11. var args = [].slice.call(arguments);
2) Vazamento do arguments
function leaksArguments() {
return arguments;
}
12. 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
13. 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!');
}
14. 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!');
}
15. 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
16. var array = [1, 2, 3];
for(var i in array) {
console.log(array[i]);
}
5) For-in em objetos com índices numéricos
17. 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);
});
18. 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);
}
}
19. 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);
}
}
20. 7) Parâmetro de tipo não esperado
var obj = { prop1: 1 };
function test(param) {
param.prop2 = 2; // não tem `prop2`
}
test(obj);
21. 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);
26. 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;
}
}
27. for(var item of array) {
console.log(item);
}
12) Uso de for-of
28. 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);
});
29. 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
● ...
33. TurboFan
● Novo JIT do V8
● Trabalha após o
Crankshaft
● Otimizações mais
sofisticadas
● Eventualmente
substituirá o Crankshaft
TurboFan no Chrome 41
34. 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