Benchmark PHP X Elixir
Tags: elixir, php, benchmark, memory
Published: 2021-03-20 19:25:31

---
title: Benchmark PHP X Elixir
published: true
description: Benchmark e Memória utilizada usando Elixir/PHP
tags: elixir, php, benchmark, memory
//cover_image: https://direct_url_to_image.jpg
---

## Introdução

Estou a 30 dias estudando Elixir, eu não tenho intenção nem de denegrir a imagem do Elixir que estou apaixonado e nem de enaltecer o PHP e minhas considerações sobre Elixir podem ser equivocadas aja visto que há muito ainda para eu aprender.

Em uma das aulas propostas pelo curso tinha a leitura de um arquivo de 300 mil linhas para gerar um relatório. Depois de gerado o relatório uma melhoria no relatório dividindo o arquivo em 3 e processando fazendo uso do concorrência.

Os resultados foi surpreendente ao fazer uso de concorrência, processando 3 arquivos ao mesmo tempo, foi aproximadamente 33% do tempo, mas aqui que começa ficar bom, eu pensei: E o PHP, quanto tempo ele levaria para fazer o mesmo processo?

## Brincadeira começa aqui.

Bom para fazer comparação entre PHP e Elixir eu multipliquei as linhas fazendo o relatório ter 9 milhões de linhas.

E vou utilizar o time, para medir o início e o fim de cada resultado, não vou postar vários resultados, você poderá testar ao final cada um quantas vezes quiser e ver o resultado por você mesmo.

### Versões utilizadas
Elixir 1.12-dev e 1.11.3
PHP 8.0 e 7.4

### Elixir - Arquivo único

`time -vvv mix run init-complete.exs`

User time (seconds): 24.19
Percent of CPU this job got: 124%

Memória utilizada em todos os testes do Elixir variou de 28 a 33 megas. Usando :erlang.memory(:total) para saber a quantidade de memória utilizada.

### PHP - Arquivo único teste 1 - com debug

O primeiro teste foi similar ao do Elixir com a diferença de utilizar 3,7 gigas de memória, só que eu tentei executar o mesmo no Mac que só tem 8 Gigas de memória e não executou, somente no meu PC e no meu Notebook que tem 64GB de Memória ram, porém em outro teste com arquivo menor o de 300 linhas no Mac o tempo ganhava do Elixir. Eu fiquei intrigado, descobri o motivo: no Mac o Debug não estava ativado.
Por isso não coloco o resultado do primeiro teste do php, acho irrelevante, mas acho relevante mencionar o debug ligado que pode alterar muito o resultado.

### PHP - Arquivo único teste 2 - sem debug

`time -vvv php reports/report.php`

User time (seconds): 8.51
Percent of CPU this job got: 99%
Memória Utilizada: 3,7 Gigas

Bom PHP ganha no tempo, no uso da CPU, mas perdeu de lavada no uso da memória. Foi então que meu amigo [Bruno](http://github.com/ibrunotome) me lembrou da existência do yield no PHP que eu já tinha lido, mas nunca usei, fui procurar como usar e fiz um novo teste.

### PHP - Arquivo único teste 3 - sem debug e com yield

`time -vvv php reports/yield.php`

User time (seconds): 6.13
Percent of CPU this job got: 99%

O uso da CPU continuou o mesmo,porém o tempo caiu quase 3 segundos, além que o uso de memória ganhou de lavada do Elixir neste caso, pois usou apenas 2 megas de memória, isso mesmo, você leu corretamente, 2 megas. Até no Mac eu consegui executar este teste, que antes não era possível pela capacidade de memória.

Então eu dividi os arquivos em 3 e fui fazer o teste com concorrência.

### Elixir concorrência - 10 arquivos

`time -vvv mix run init-many10.exs`

User time (seconds): 41.69
Percent of CPU this job got: 903%

Tempo aumentou muito, e o uso do processador, achei que coloquei muitos arquivos, então dividi em 3 apenas e depois com 2 arquivos vou colocar o resultado só com 2 arquivos que achei mais relevante e de menor tempo.

### Elixir concorrência - 2 arquivos

`time -vvv mix run init-many2.exs` (ops, usar o time para este teste pareceu injusto, visto que por algum motivo ele fica o dobro do tempo).

Então para este teste, executei via terminal:
```shell
iex -S mix
:timer.tc(fn -> ReportsGenerator.build_from_many(["outaa", "outab"]) end)
```

10 segundos. Memória sempre se manteve aproximadamente a mesma.

Uso de CPU caiu relacionado a processar 10 arquivos ficando em 300%, o tempo caiu pela metade, embora ainda assim o php sem concorrência ganhou no tempo.

### PHP concorrência

Eu não fiz o teste com concorrência em PHP, pois é necessário usar ferramenta como Swoole, além do tempo para refatorar o código de moda a usar coroutine.

## Conclusão

Os testes não são conclusivos, porém o PHP se mostrou com desempenho melhor mesmo sem usar concorrência, mas devemos considerar que eu executei o Elixir em modo de desenvolvimento, se executar em modo produção os valores podem serem alterados consideravelmente devido a bibliotecas que não serão carregadas em produção assim como aconteceu ao desativar o debug do PHP, mas ainda não coloquei nada em produção da forma correta para poder ser mais justo com Elixir, então fica a seu cargo testar.

P.S.: PHP não usou o recurso de JIT, até achei que ele estava fazendo uso na versão 8.0, porém executei o teste utilizando a versão 7.4 que não tem JIT e o tempo foi o mesmo ou com tempo insignificante de diferença.

Seria bacana ver os mesmos teste em Go e Rust, eu gostaria muito de ver os resultados, alguém se habilita?

Se você quiser fazer seus próprios testes ou até mesmo colocar o PHP em concorrência, segue os scripts que utilizei: [https://github.com/emtudo/reports_generator](https://github.com/emtudo/reports_generator)