Como testar o tempo de execução do seu código com JS
Assim como eu, em algum momento você já deve ter pensado: Como saber o tempo de execução do meu código? Como vou saber o quão performático ele é?
Existem duas funções nativas bem interessantes que estão disponíveis nas Web APIs dos navegadores. Com essas funções é possível medir e analisar o tempo de execução de um código JavaScript.
O processo de funcionamento é relativamente simples, basta iniciar e encerrar um cronômetro, e automaticamente ele irá mostrar no console o tempo que levou para terminar a execução.
Essa API pode nos ajudar de diversas maneiras, seja na criação ou na melhoraria de nossos algoritmos.
Vamos comparar um cálculo matemático utilizando dois laços de repetição com a mesma finalidade, porém, somente um deles será performático. Qual deles será o melhor?
Então vamos por a mão na massa.
Começaremos criando uma função que retornara valor conforme a formula existente nessa função.
function someCalc(index) { return index * 5 + 1 / 3 * 8; }
Podemos perceber que a função que criamos pega um número que será o index do laço de repetição, onde iremos realizar algumas operações. Enfim, será que já conseguimos testar algo com ela? Sim, vamos agora ao próximo passo.
var arr = []; for (var i = 0; i < 10000; i++) { arr[i] = i; }
Agora criamos um for para alimentar um array de 10000 posições para nos auxiliar nos próximos passos. Agora de fato iremos ver o console.time(), que nada mais é a função que vai disparar a contagem do nosso cronômetro. Essa chamada deve sempre ir no início da função.
console.time('#forEach'); arr.forEach( (item, index) => { item = someCalc(item); } ) console.timeEnd('#forEach');
Conforme o código acima, podemos notar que já colocamos junto o fim do cronômetro, a função console.timeEnd(), onde ela teoricamente está dizendo ao cronômetro: pare e me informe o tempo.
Agora iremos replicar ambas as função console.time() e a console.timeEnd() usando o for, após isso veremos qual foi o tempo de execução de cada uma delas. Já devem estar se perguntando qual é mais performática. Calma, já estamos chegando nessa parte.
console.time('#for'); for(let i=0; i < arr.length; i++){ arr[i] = someCalc(arr[i]); } console.timeEnd('#for');
Tendo em vista ao algoritmo acima, veja abaixo os resultados.
#forEach: 0.81982421875ms #For: 2.466796875ms
Neste caso o forEach foi mais performático, mas é importante deixar claro que cada caso é um caso.
O for poderá ser mais rápido, ou while, tudo vai depender da situação. Ou até mesmo da engine que tiver usando, onde este teste foi feito no Google Chrome, mas realizei outro teste no Firefox e teve um comportamento diferente. Os testes foram feitos também no JSPERF. Segue abaixo as imagens que ilustram os testes.
1. Google Chrome
Testando o algorítimo no JSPERF
2. Firefox
Teste de perfomance firefox javascript
Será que existe outra forma para validar isso?
Existe, só que em vez de usarmos os console.time/End, iremos utilizar o performance, mas o uso dele é um pouco diferente. Veja abaixo:
var timeStart = performance.now(); for(let i=0; i < arr.length; i++){ arr[i] = someCalc(arr[i]); } var timeEnd = performance.now(); // In this case it took 1.069...92433 ms console.log("Duration " + (timeEnd - timeStart) + " ms . . .");
É importante salientar que essa função do exemplo acima não existe no Node.js, lá a gente usa o Date.now(), ou seja, você implementa que nem o exemplo do performance substituindo pelo Date.now()
Espero ter colaborado com o aprendizado de vocês, dúvidas ou sugestão pode ser criada um ISSUE no repositório.