Eficiência Matemática
Autor: Ricardo Soares de Lima | Publicado: 2013-03-06T17:06:00-08:00

Vou mostrar-lhes dois trechos de código que fazem exatamente a mesma coisa:






Analisem os trechos de código e tentem descobrir o que eles fazem. Uma dica: a&nbsp;essência de tudo está na função calc.


Já analisou? Entendeu o que está acontecendo? Bom, estes trechos de código calculam&nbsp;1 milhão de vezes a soma do intervalo de números entre 1 e um número aleatório entre 1 e 500. Ao mesmo tempo ele toma nota de quanto tempo este processo leva&nbsp;usando a função microtime.


Você conseguiu descobrir o que estava acontecendo antes de eu ter explicado? Se&nbsp;você não conseguiu, não tem problema, eu vou explicar. Comparando os dois trechos de código, qual você diria que apresenta com mais&nbsp;clareza o comportamento que expliquei anteriormente?


O primeiro trecho usa funções cujos nomes dão uma certa ideia sobre o que está&nbsp;acontecendo. "array_sum" retorna a soma dos valores dentro de um array. "range" retorna&nbsp;um array preenchido com números em um intervalo que vai do primeiro parâmetro&nbsp;passado até o segundo parâmetro passado. Então array_sum soma o conteúdo de um array,&nbsp;range retorna um array de números, bingo! Tudo o que o loop faz é somar os números&nbsp;naturais de 1 até um intervalo superior que varia de 1 até 500. Um milhão de vezes!


E o segundo trecho? Não há chamadas de funções nesta versão da função calc. Ela mais&nbsp;parece uma fórmula matemática. E realmente é, é a seguinte fórmula:


E ela simplesmente retorna a soma entre os números naturais de 1 até n.

Certo! O que eu quero demonstrar com tudo isso? Primeiro eu convido vocês a executar os trechos de código em seus computadores e comparar o tempo gasto nos cálculos tanto pelo trecho usando array_sum quanto pelo outro usando a fórmula matemática, no meu computador um core i7 2600 3,40 GHz os tempos em segundos, cada trecho foi executado três vezes, foram os seguintes:

array_sum:


42,979010105133
42,527684926987
43,008407831192

fórmula matemática:


9,8508331775665
9,889456987381
9,9301979541779

Não é um benchmark rigoroso ou bem feito, mas como vocês podem ver a diferença de tempo entre as duas abordagens rodando no meu computador é enorme. E acredito que aqueles que testarem o código também observarão grandes diferenças de tempo de execução dos dois trechos.



Eu acredito que a grande diferença de eficiência de execução se deve principalmente a dois pontos principais. A função range cria um array dinamicamente e isso envolve alocação de memória por parte do interpretador PHP, o que toma tempo. Mas é o segundo ponto que deve realmente impactar na performance, a função array_sum deve percorrer cada elemento do array gerado pela função range e laços de repetição afetam a performance significativamente.



Eu não tenho dúvidas de que o código usando array_sum é mais fácil de se ler, mais elegante e usa todo o poder do dinamismo da linguagem PHP. Mas a eficiência da abordagem matemática é inegável, e alguns até poderiam dizer que ela é tão elegante quanto a outra, sempre podemos adicionar um comentário informando o que a fórmula faz, não é? Acho que preciso voltar a estudar matemática.