Flatten Array com Ruby - Versão 2
anchietajunior / March 2020 (323 Words, 2 Minutes)
Ontem, dia 14/03/2020 publiquei um post sobre o algoritmo FlattenArray em Ruby, porém não fiquei satisfeito com o código resultado da primeira vez que fiz. Então hoje, dia 15/03/2020 (isso mesmo, um dia depois :D) resolvi fazer uma nova versão desse algoritmo e analisar o que eu poderia ter feito melhor na primeira vez.
Problemas com a primeira versão
Listando os problemas encontrados na primeira versão
Legibilidade
Quanto mais linhas de código, mais tempo leva para se ler, isso é fato.
Função dentro de outra função
Para executar a recursividade, criei uma função dentro da função principal responsável por executar a recursividade do algoritmo.
Variável de instância
Para não perder a referência durante a recursividade, tive de apelar para uma variável de instância @new_array, o que piora ainda mais o tempo de execução e a legibilidade.
Reescrevendo
Versão atual.
def flatten2(array, flattened_array = [])
for i in array do
if i.is_a?(Array)
flatten2(i, flattened_array)
else
flattened_array << i
end
end
flattened_array
end
Benchmarking
Podemos fazer alguns testes de tempo de execução utilizando uma lib nativa do Ruby chamada Benchmark.
# Versão 1
require 'benchmark'
puts Benchmark.measure {
10000.times do
flatten([1, [2, [3, [4, [5]]]], [6, [7], [8]]])
end
}
# Resultado
0.036546 0.000184 0.036730 ( 0.036857)
=> nil
# Versão 2
require 'benchmark'
puts Benchmark.measure {
10000.times do
flatten2([1, [2, [3, [4, [5]]]], [6, [7], [8]]])
end
}
# Resultado
0.030918 0.000242 0.031160 ( 0.031432)
=> nil
Diferença pequena hein? Só que não, imagine isso sendo executado milhões de vezes por minuto, faria total diferença.
Conclusão
A versão atual, instancia um novo array chamado flattened_array quando executada direto nos parâmetros, removendo a necessidade de uma variável interna e pior ainda, uma variável de instância interna.
Além disso, posso remover a função interna e executar a recursão fazendo referência ao array flattened_array nos parâmetros.
Convenhamos, @new_array também não diz nada sobre o que está sendo retornado nessa variável, portanto, nomenclatura é outra coisa que foi resolvida.
Bem mais legível e faz mais sentido que a versão anterior, essa é a maior vantagem que temos ao nosso favor, a autocrítica.
Isso nos tempos modernos de desenvolvimento é chamado de débito técnico que podemos ir pagando com o tempo, é provável que eu faça um post sobre isso em breve, mas de forma resumida, o poder de escrever um código, critica-lo e reescrevê-lo de uma forma melhorada, é muito massa.
Então, é isso. Let’s code and let’s refactor that code!