Softa

Aplicações Web 2.0 com Ruby on Rails e Postgres 
Filed under

mailee

 

Comparando a performance de implementações do Ruby (1.8 x 1.9 x JRuby x Rubinius)

Em primeiro lugar, nunca confie em testes de performance alheios por isso durante o post vou dar as ferramentas para que o leitor reproduza os testes no seu ambiente se assim o desejar. 

Em segundo lugar a minha intenção não era fazer um teste abrangente, mas sim detectar diferenças de performance em um recurso bem específico: threads.

Antes de simplesmente jogar os resultados dos testes na tela, vejamos o que me levou a eles.

Aqui na empresa o Mailee trabalha fortemente com execução concorrente de código. A versão atual do nosso software de entrega implementa a concorrência com threads. Já considerei diversas vezes a migração para uma arquitetura multi-processo, idéia que ainda não foi descartada. No entanto, atualmente o trabalho para migrar para processos parece maior que o benefício, o que me fez pensar em otimizar o código e procurar uma boa implementação de threads em Ruby.

Os testes e o ambiente:

Bom, aos testes. O ambiente de testes utilizado foi um MacBook com processador Core 2 Duo de 2.4 GHz executando o Mac OS X 10.5.8, os resultados são a média de 10 execuções.

Realizei um teste para multi-threading limitado pelo IO (I/O bound) e um para multi-threading limitado pela CPU (CPU bound). Cada teste foi executado inicialmente com apenas um thread, e depois aumentando a carga de trabalho linear e uniformemente até 10 threads simultâneos. Abaixo o código dos testes:

Resultados:

Conclusões:

É curioso observar que embora o MRI 1.9.1 tenha melhorado drasticamente sua performance para os threads IO bound, quando o recurso é CPU ele fica parelho e um pouco pior comparado ao MRI 1.8.7.

A performance do jruby no teste de CPU me decepcionou, mas a lentidão pode ser relacionada a JVM do Mac OS X.

Pelos resultados apenas desses dois testes eu ficaria com o MRI 1.9.1 ou com o Rubinius. Mas é importante ressaltar que a versão 1.0 do Rubinius não é compatível com o Ruby 1.9, mas sim com o Ruby 1.8.

E não percam a seguir:

Ainda pretendo publicar um teste comparativo usando o conjunto de benchmarks diponível em http://github.com/acangiano/ruby-benchmark-suite, mas isso fica para um post futuro. No meu próximo post pretendo apresentar testes similares feitos com um código semelhante porém utilizando processos ao invés de threads.

 

Filed under  //   benchmark   jruby   mailee   performance   rubinius   ruby   testes   threads  
Posted by Diogo Biazus 

Comments [0]

Mailee Metal

Hoje coloquei no ar uma nova versão do Mailee. As novidades são:
  • Reenviar mensagem
  • Desativar templates
  • Melhorias de performance
Para os desenvolvedores, a grande novidade é o uso do Metal, que entrou no Rails 2.3.2. Trata-se de um micro-framework embutido, para ser usado em chamadas muito usadas nas aplicações, como métodos Ajax ou coisas do gênero. No nosso caso, resolvemos aproveitar o recurso e reescrever o método “go/view” responsável por receber um “aviso” de que um contato viu uma determinada mensagem, buscar dados geográficos e armazenar o acesso no banco.

O código ficou mais ou menos assim:
go_1.png
Como você pode ver, o (\d+) recebe o ID da visualização ($1), sem precisar de abstrações como “params”. Além disso, meu controle “Go” continua funcionando 100% com os outros métodos. E veja alguns benchmarks:

Sem Metal: 16.45 requests/segundo Com Metal: 34.59 requests/segundo

Grande recurso, hein?

Filed under  //   desenvolvimento   mailee   rails  
Posted by Pedro Axelrud 

Comments [0]

Relatórios geográficos no Mailee

Esta semana liberamos o novo sistema de relatórios do mailee. É possível visualizar o resultado dos envios por cidade, por país e também com um gráfico exclusivo do nosso país (sim, o Brasil…). Quem quiser saber mais, dá uma olhada lá no tour
reports_country.png
Esse sistema foi construído em cima da ótima biblioteca em C da MaxMind, que foi a mais rápida e completa que encontramos, com o binding GeoIPCity em Ruby feito por rydahl
reports_world.png
A instalação disso tudo é relativamente simples, e o código necessário para caputar os dados muito conciso:

require 'geoip_city'    
geoip = GeoIPCity::Database.new('/usr/local/share/GeoIP/GeoLiteCity.dat')    
result = geoip.look_up(SEU IP AQUI)

Em breve muito mais…

Filed under  //   desenvolvimento   mailee  
Posted by Pedro Axelrud 

Comments [0]

Invertendo o jogo com um modelo diferente

Na semana passada eu tive uma reunião com um parceiro nosso cuja opinião a gente respeita muito. E pela primeira vez (depois de algumas poucas apresentações do Mailee antes ainda de lançar) eu escutei a pergunta que eu esperava ouvir: “qual é a mágica desse novo modelo de preços?”.

Esclarecendo um pouco, o Mailee é cobrado por número de contatos e não por envios. O usuário decide quantas mensagens vai enviar ao longo do mês. E, quando se compara entre concorrentes brasileiros e o Mailee, os nossos preços por número de contatos ficam ainda abaixo do preço por envio da concorrência. Ou seja: com o que o cliente normalmente paga por um envio, no Mailee ele faz quantos envios quiser, dentro de um mês.

Por isso eu esperava a pergunta. E fiquei feliz quando ela foi a primeira coisa que este parceiro me perguntou. A resposta, porém, não tem mágica e se resume em duas coisas: custos enxutos e tolerância zero com spammers. Custos enxutos significa ter um engine de envios esperto e uma empresa pequena, com planos de permanecer pequena. Isto é 50% da “mágica”. Ou outros 50% vêm de uma confiança de que o Mailee vai ajudar os clientes a fazerem o melhor e-mail marketing e de um processo inteligente para evitar abuso e spam.

A principal conseqüência dessa abordagem é que o Mailee é focado em clientes mais qualificados a fazer marketing direto ou que o façam através de agências especializadas. E já fica um aviso aqui: quem quiser fazer spam, melhor buscar outra solução. Os demais, sejam bem-vindos!

 

Filed under  //   desenvolvimento   mailee  
Posted by Pedro Axelrud 

Comments [0]