Diz o ditado que quando a única ferramenta que você tem é um martelo todos os problemas parecem um prego. E o pior é que vira-e-mexe eu me deparo dando martelada em parafuso ou algo que o valha.

Eu sou um grande fã de shell script. Acho extremamente eficiente, simples, funcional e, se você conhecer comandos e truques o suficiente consegue fazer coisas realmente impressionantes com 1 linha.

Pelo menos uma vez ou duas por dia alguém vem na minha sala com algum pedido para fazer um script ad-hoc pra resolver algum problema, fazer parse de algum arquivo ou update em massa de sabe-se lá o que. Invariavelmente resolvido com um for loop, um sed ou tr ou grep (ou todos juntos) e vamos que vamos.

Mas semana passada me apareceram com um interessante: Um arquivo com +20.000 linhas e um outro com +170.000 linhas. O menor tinha uma lista de UPCs (códigos de barra) e seus respectivos códigos internos enquanto o maior tinha uma lista com diversas colunas sendo uma delas o UPC.

Minha tarefa, caso eu desejasse aceitá-la, era substituir o UPC no segundo arquivo pelo código interno. Simples, né? Nem pensei duas vezes antes de fazer um one-liner que me gerou um terceiro arquivo com todas as linhas do arquivo menor parseadas num script sed mais ou menos assim:

Depois foi só botar pra rodar um sed -f arquivo.sed -i arquivao.txt e ir fazer minhas coisas. Menos de 2 minutos pra já estar pensando em outros problemas.

Só depois que percebi o quão estúpido isso foi. Para cada linha de sed o arquivo de +170000 linhas teria que ser aberto, examinado linha a linha, ter as substituições feitas e fechado. O total de repetições seria de 20.000 x 170.000 = 3.400.000.000

Não me liguei disso no momento, deixei rodando num shell à parte e só depois de três horas, quando cliquei na janela novamente e vi que ainda rodava (e consumia quase 100% de CPU no servidor) pensei que tinha algo errado. Eu estava martelando um disjuntor.

Fazia meses que não relava em Python, mas achei que seria uma solução melhor usando um dicionário. No final o script ficou assim:

Tempo de execução? 2 segundos.

A lição pra mim é que nem sempre o que é mais fácil de criar ou pensar vai ser mais eficiente para resolver o problema. Não me importo de um script demorar 10 minutos pra rodar se eu só gastei 30 segundos criando um one-liner ao invés de 15 minutos criando algo mais caprichado que rodaria em 1 minuto.
Mas um script rodar mais de 3 horas enquanto eu poderia ter gasto 10 minutos e depois executado o mesmo em 2 segundos foi de causar vergonha.