Tenho passado algumas horas do dia obcecado com probleminhas do Project Euler, brincando cá e lá com idéias novas tanto sobre Matemática quanto sobre programação. Sorte minha ter colegas de trabalho egressos do IMPA, especialmente um tão paciente quanto o Zé Luiz.
Como a intenção é me divertir e aprender mais Matemática, escolhi o Ruby pra ser meu amigo na jornada. É o que me dá aquela sensação de bem estar agradável, e eu confesso que adoro escrever array.inject {|k, v| k * v} e alterar Fixnum para colocar um método factors babaca.
O lance é que eu não sou lá brilhante, então nem sempre tenho a abordagem mais eficiente de cara (ou mesmo o ferramental matemático para chegar até ela). Alguns dos problemas também exigem um pouco de força bruta, então quando chega na hora do bichinho ter de fazer muitas multiplicações e divisões para ficar dentro da marca ideal de no máximo um minuto de execução, Ruby fica mais pra Rubinho.
Sabendo que seria assim, decidi que seria o melhor momento para ver qual é a do RubyInline. Eu tinha escrito métodos para fatorar e verificar se um número é primo que se comportavam bem com números abaixo de 10 mil, mas que começavam a tartarugar acima disso. Num problema como o décimo, em que deve-se obter a soma de todos os números primos abaixo de um milhão, a performance era risível.
Reescrevi os meninos todos em C. De três minutos para o problema 10 em Ruby puro, passei para 13 segundos (com a compilação do módulo inline). E não tem nada demais na versão em C, nenhum deslocamento de bit maluco, nada. Minha implementação original para problema 14, totalmente força-bruta, teve um ganho ainda maior: saiu de aproximadamente 4′30″ para 3.6″.
É muito reconfortante ter a opção de melhorar dramaticamente a performance quando necessário. É óbvio que ter um runtime tão pouco eficiente quanto o interpretador do Matz não ajuda muito a linguagem (ao menos até a maturidade da YARV), e que isso deve ser consertado quanto antes. Mas a API em C super bacana e a robustez da mais tried-and-true das linguagens faz com que a ponte fique muito fácil de se atravessar.
0 Respostas para “<3 RubyInline”