O hardware é barato, os programadores são caros

Dado o rápido avanço da Lei de Moore, Quando faz sentido usar hardware em um problema de programação? Como regra geral, eu diria que quase sempre.

Considere a salário médio de programador aqui nos EUA:

gráfico de salários de programadores, no final de 2008

O senhor provavelmente tem vários desses programadores na equipe. Não posso dizer quanto custam seus servidores ou quantos deles o senhor pode precisar. Ou talvez o senhor não precise de nenhum – talvez todo o seu código seja executado no hardware dos usuários, o que é um cenário totalmente diferente. Obviamente, as situações variam. Mas mesmo a matemática mais rudimentar dirá ao senhor que seria necessário um maciço para igualar os custos anuais até mesmo de uma modesta equipe de programação de cinco pessoas.

Por exemplo, acabei de comprar o dois servidores muito potentes para o Stack Overflow. Mesmo depois de contabilizar um terceiro servidor de backup e discos rígidos sobressalentes para as matrizes RAID, meu gasto total é de cerca de US$ 5.000. Esses servidores, comparados com os que temos agora, oferecem:

  • aproximadamente 50% mais velocidade de CPU
  • 2 a 6 vezes a capacidade de memória
  • quase o dobro do espaço em disco (e é uma matriz RAID 10 mais rápida)

Sob esse novo regime de hardware, podemos esperar que os tempos médios de resposta de página melhorem em cerca de metade. Tudo isso para menos de um mês do salário médio de um programador.

Eu diria que isso é um ótimo negócio. Até mesmo um negócio fácil.

A propósito, é também por isso que deixar de equipar seus programadores (relativamente) bem pagos com equipamentos decentes, de acordo com a Declaração de Direitos do Programador é um erro colossal. Se um investimento único de US$ 4.000 em cada programador fizer com que eles sejam apenas 5% mais produtivos, o senhor terá um ponto de equilíbrio após o primeiro ano. Depois disso, todos os anos o senhor terá lucro. Além disso, ter programadores que acreditam que seus empregadores realmente se importam com eles é provavelmente uma boa estratégia de negócios para empresas que realmente querem estar presentes daqui a cinco ou dez anos.

Claramente, o hardware é barato e os programadores são caros. Sempre que o senhor tiver a oportunidade de aproveitar esse desequilíbrio, seria incrivelmente tolo não o fazer.

Apesar da maravilha duradoura do desfile anual de hardware mais novo e melhor, também seria bom lembrar meu gráfico favorito de todos os tempos do Pérolas de programação:

TRS-80 versus DEC Alpha

Tudo é rápido para pequenos n. Quando n fica grande, é quando as coisas começam a desandar. O gráfico acima de um antigo Trash-80 a derrubada de um semi-moderno DEC Alpha é um lembrete preocupante de que o o hardware mais rápido do mundo não pode salvá-lo de um código ruim. Mais especificamente, estruturas de dados ou algoritmos mal escolhidos.

Isso não acontecerá ferir executar um código mal escrito nas caixas mais rápidas que o senhor puder usar, é claro. Mas se o senhor quiser obter melhorias tangíveis no desempenho, muitas vezes terá que se empenhar e otimizar o código também. O livro de Patrick Smacchia lições aprendidas com o foco no desempenho no mundo real é um excelente estudo de caso em otimização.

gráfico de otimização dependente

Patrick conseguiu aprimorar o nDepend o desempenho da análise quadruplicou e reduziu o consumo de memória pela metade. Como previsto, a maior parte desse aprimoramento foi de natureza algorítmica, mas pelo menos metade do aprimoramento geral veio de uma variedade de técnicas de otimização diferentes. Patrick compara isso com seus primeiros dias escrevendo código de cena de demonstração no Commodore Amiga:

No início dos anos 90, participei da cena de demonstração do Amiga. É uma ótima ilustração da ideia de que o sempre há espaço para um desempenho melhor. Todas as demonstrações foram executadas no mesmo hardware. Esse foi o incentivo perfeito para que os desenvolvedores de demonstrações produzissem códigos cada vez mais otimizados. Durante vários anos, todos os meses algum recorde era batido: o número de polígonos 3D, o número de sprites ou o número de pontos exibidos simultaneamente a uma taxa de 50 quadros por segundo. Em um período de alguns anos, o fator de desempenho obtido foi de cerca de 50 vezes! Imagine o que significa realizar em um segundo um cálculo que originalmente levava um minuto inteiro. Esse enorme ganho foi o resultado de algoritmos melhores (com muitos pré-computadores e delegações a subchips) e micro-otimizações no nível da linguagem de montagem (melhor uso dos registros do chip, melhor uso do conjunto de instruções).

Patrick obteve resultados extraordinários, mas vamos deixar claro: otimizar seu código é difícil. E, às vezes, perigoso. Não é algo que se faça de ânimo leve, e o senhor certamente gostaria que seus programadores mais qualificados trabalhassem nisso. Para colocar isso em perspectiva, vamos buscar algumas citações clássicas.

Regras de otimização:

Regra 1: Não faça isso.

Regra 2 (somente para especialistas): Não faça isso ainda.
M.A. Jackson

Mais pecados de computação são cometidos em nome da eficiência (sem necessariamente alcançá-la) do que por qualquer outro motivo, incluindo a estupidez cega.

W.A. Wulf

Os programadores têm a tendência de se perder nos detalhes da otimização pela otimização, como já observei anteriormente em Por que minhas otimizações não estão sendo otimizadas? e Micro-otimização e almôndegas. Se o senhor não for extremamente cuidadoso, poderá acabar gastando muito de tempo de desenvolvimento muito caro com muito pouco para mostrar. Ou, pior ainda, o senhor se verá diante de uma série de novos bugs, ainda mais sutis, em sua base de código.

É por isso que recomendo a seguinte abordagem:

  1. Lance hardware barato e mais rápido no problema de desempenho.
  2. Se o aplicativo agora atende às suas metas de desempenho, pare.
  3. Faça um benchmark de seu código para identificar especificamente onde estão os problemas de desempenho.
  4. Analise e otimize as áreas que o senhor identificou na etapa anterior.
  5. Se o aplicativo agora atender às suas metas de desempenho, pare.
  6. Vá para a etapa 1.

Sempre tente gastar para sair de um problema de desempenho primeiro lançando um hardware mais rápido sobre ele. Muitas vezes, essa é uma maneira mais rápida e barata de resolver problemas imediatos de desempenho do que tentar resolver o problema com código. A longo prazo, é claro, o senhor fará as duas coisas. Eventualmente, o senhor será forçado a revisitar as preocupações algorítmicas mais profundas e os problemas de design do seu código que impedem que o aplicativo seja executado com mais rapidez. E a vantagem de fazer isso em um novo hardware é que o senhor parecerá ainda mais maior quando o senhor oferece o duplo golpe do código otimizado executado em um hardware mais rápido.

Mas, até o dia em que a Lei de Moore nos deixar completamente na mão, uma coisa é certa: o hardware é barato – e os programadores são caros.