Reduzindo consumo de memória em aplicações Ruby de forma fácil
Durante a criação da gem attributes_sanitizer acabei precisando rever algumas boas práticas de desenvolvimento Ruby e descobri que Matz, o criador do Ruby, já indicou que a versão 3.0 do Ruby irá remover o suporte à strings mutáveis e que precisamos nos preparar para tal mudança.
O que são strings mutáveis? Simples: uma string cujo valor podem ser alterado depois que ela for instanciada. Exemplo:
O Ruby sempre utilizou strings mutáveis por padrão. Isso permite que você altere o valor de uma string quando quiser, como é o caso acima. O problema disso é que você acaba alocando strings intermediárias e isso aumenta o consumo de memória da aplicação.
É por isso que é normal em constantes vermos algo assim:
O .freeze
força que aquela string se torne imutável no Ruby.
O problema toma maior volume quando percebemos que a implementação de Hash do Ruby para chaves strings aloca muita memória.
Para verificar se um código está utilizando string mutável basta executar o arquivo .rb
adicionando a seguinte flag:
E também é possível adicionar um comentário mágico à seus arquivos que força o comportamento automaticamente:
Mike Perham, há algum tempo, indicou que em simulações de geração de 30.000 jobs ele conseguiu uma redução de 100MB no consumo total de memória, uma redução de aproximadamente 20%.
Adicionei esse comentário mágico na minha gem e acho que seria muito interessante aplicar o mesmo conceito nas nossas aplicações.
Esse outro artigo da honeybadger também fala bastante sobre o assunto: https://blog.honeybadger.io/when-to-use-freeze-and-frozen-in-ruby/.
É importante dizer que ainda será possível ter strings mutáveis utilizando o String.new
para garantir que esta mudança não irá quebrar sua aplicação é muito importante ter uma boa suíte de testes.