Otimização X Produtividade

Um assunto que sempre me chamou atenção foi a otimização e que junto me trouxe grandes duvidas referentes a Produtividade X Otimização, pois cada vez mais vejo grandes empresas lutando por milissegundos que mesmo parecendo pouco tem valores significativos no faturamento final de uma grande empresa ou até mesmo poder de atração para novos usuários.
Acontece que atualmente, temos frameworks que melhoram muito a produtividade de grandes e pequenos projetos, mas quando se pensa em otimização, isso pode ser prejudicial para um site que vira a se tornar grande?
Sei que vários fatores são importantes para agilizar um sistema ou site, mas levando em conta a escolha do framework , ou até mesmo dispensar um framework pode ser uma opção inteligente? Ou a linguagem, que embora dependa muito do potencial do programador, ainda sim existem linguagens que possuem melhor poder para otimização do que a outra?
Ainda sou leigo no assunto, mas estou tentando entender melhor agora para poder desenvolver melhor depois.
Peço desculpas se falei alguma bobagem, mas estou tão intrigado com esse assunto que gostaria de saber a opinião de vocês.
Sei que Java é uma linguagem excelente tanto quanto todas as outras no mercado, cada uma com sua particularidade , mas quando o assunto é otimização quais são as melhores opções no mercado, tanto quanto para linguagens quanto para frameworks?
Creio que esse assunto deve ser levado em conta, pois se você pretende que seu sistema um dia cresça não tem como não levar em conta esse importante fator.

Tem esse post aqui do ViniGodoy que fala sobre performance, mais sobre otimização.

Se você ler, vai ver que a coisa é muito mais conceitual, do que dependente da linguagem.

Não estou dizendo que todas as plataformas são iguais, claro que não, mas sim que em todas as plataformas, os passos para otimização são parecidos, existem técnicas pra isso, o que fazer, como fazer, etc.

Dê uma lida, vê se te clareia um pouco as ideias.

Siga o que fez o Twitter: use um framework em que seja fácil botar rapidamente o site no ar (time to market).

Se for um sucesso, otimize - ou seja, use um framework mais rápido e remova as funcionalidades que não são usadas.

Quando se faz a análise de um sistema, normalmente ocorre de acabar especificando funcionalidades desnecessárias e não ter algumas funcionalidades necessárias e muito desejadas.

Numa primeria visão , Produtividade e Performance não são relacionadas. São ortogonais.
Estamos comparando o quanto uma equipe é rápida e eficiente a escrever código (produtividade) e quanto esse código é executado rápida e eficientemente pela máquina (performance).

Como regra geral não existe Otimização até que você consiga medir o problema. O uso de profilers, por exemplo, é mandatório.
Também como regra geral vc não deve usar dialetos especialmente desenhados para aumentar a performance. Em java isso constuma ser completamente contra-producente porque o otimizador de bytecode da jvm funciona bem quando o codigo é bem escrito. ( um dialeto é uma forma especifica de usar a sintaxa que a linguagem tem - por exemplo , para iterar uma lista vc pode usar o for-extendido, o for com iterator, ou o while com iterator. funciona igual, o resultado é o mesmo, mas a facilidade de leitura e o que o compilador e a jvm fazem é diferente)

É mais importante escrever o que vc quer significar do que as instruções básicas (“say what you mean, do not say what you want”). O exemplo clássico é usar o for extendido para arrays. Embora vc possa usar variáveis de iteração no for este dialeto é uma forma de otimização (que viola o ecapsulamento). usar for extendido é melhor porque representa o que vc quer dizer e não importa como é implementado. O compilador saberá fazer a otimização necessária.

Algumas coisas mais complexas como trabalhar com threads requerem que vc saiba o que está fazendo , mas mais uma vez o que salvará é o seguimento de abstrações e metáforas que são simples de entender - sem importar a implementação - como o padrão Produtor-Consumidor. O codigo ser legivel é sempre mais importante do que ser rápido (isto porque o código é a unica documentação que está 100% sincronizada com o sistema).

Em casos muito especificos onde truques sejam necessários (em java isto é tão raro que nem sequer é um assunto interessante) os dialetos devem ser isolados em objetos especiais de forma que não vase para o resto do sistema.

Se vc manteve seu codigo limpo, facil de dar manutenção, desacoplado. Então quando existirem problemas de performance e com o profiler vc identificar onde está o gargalo vc terá mais simplicidade em realizar as alterações necessárias. Neste ponto é muito importante que não sejam fechadas portas no design do sistema assumindo que A ou B serão sempre verdade ou sempre mentira ( por exemplo, o sistema sempre funcionará localmente, ou, o servidor de bando de dados fica na mesma máquina que a jvm, etc…)

O uso de frameworks não impacta a performance a principio, mas pode impactar no final. O uso do hibernate que é tão comum pode ser um problema em certos cenários.É importante que o arquiteto saiba como os frameworks respondem, se são escaláveis, etc… se não são, então não são aptos a serem usados.

Na prática a otimização vem no meio do desenvolvimento. Coisas simples como saber inicializar um ArrayList (que infelizmente muita gente não sabe) ou saber quando usar LinkedList em vez, ou até Set , podem influcienar algoritmos e criar procedimentos inecificente. Não é uma otimização absurda, mas evita problemas à priori e ajuda a pensar nas coisas da forma correta. Por exemplo, muitos sistemas devolvem list em vez de collection e quase nunca são imutáveis. Isto pode parecer que ajuda, mas na realidade atrapalha porque causa acoplamento. No dia em que o programador usar get(i) do list, mande-o aprender a programar. As pessoas usar List com um valor semantico para dizer que os itens estão ordenados, mas normalmente isso é mentira. às vezes é melhor criar um sub-classe de collection para isso. Afinal uma interface é algo mais simples de desacoplar.

Mas ha coisas em que não vale a pena exagerar, como por exemplo usar double em vez de BigDecimal porque é mais rápido… ah! é irrelevante se é mais rápido quando não faz a mesma coisa.

O seu objetivo inicial deve ser sempre escrever bom código. Codigo limpo, facil de entender e modificar. Depois a otimização será vista depois. Se o codigo é bom, a otimização será simples. Ou seja, produtividade primeiro, otimização depois. Mas isto não quer dizer que esquecemos a otimização. As pequenas coisas, temos que ir fazendo logo, como usar arraylist corretamente. Porque esse tipo de coisas é considerado bom código.

[ resposta assumindo que vcoê está falando de webapps ]

Sobre se alguns milissegundos fazem a diferença: há muitos estudos que mostram que sim. A Amazon mostrou que 400ms mais lento na loja deles significa 1.6 bilhão de dólares a menos em vendas no ano. E tem muitos outros estudos com resultados semelhantes.

Agora, é preciso saber o que otimizar. Em aplicações Web, é consenso que 80 a 90% da performance final pro usuário se dá em aspectos de frontend (HTML, CSS, JS) e não de backend. É a chamada performance golden rule. Então às vezes gastar aquele tempo otimizando um loop em Java pode não ser tão importante quanto verificar se seu servidor tem GZIP habilitado, por exemplo.

(tenho um post sobre otimizações web com muitos tópicos, se interessar)

Primeiramente muito obrigado pelas respostas e pelo tempo cedidos por vocês para responder minha pergunta.

Estou trilhando ainda meu caminho em Java sempre colocando 1 “tijolinho” por dia afim de ter domínio sobre o assunto.

Acontece que existem muitos obstáculos quando agente tenta aprender sozinho que é o meu caso, muitas perguntas como essa surgem e você sempre fica intrigado com isso querendo saber qual a maneira correta de se fazer.

Sempre tive certeza que uma base solida é fundamental para qualquer pessoa desempenhar seu papel corretamente independentemente da área, por isso investi muito tempo aprendendo como a linguagem realmente funciona tirei minha OCJP onde aprendi MUITO e agora estou entrando no mundo web, mas estou sentindo falta de algumas coisas , que eu acho que deveria ter feito antes de começar a entrar na programação web.

Sempre vi aqui no fórum pessoas recomendando livros como o EFFECTIVE JAVA e DESIGN PATTERNS mas acho que fiz errado em querer aprender Java para web antes de aprender a como realmente programar bem.

Entendi nas respostas que a otimização deve ser feita posteriormente, e que o framework pode prejudicar no desempenho da aplicação e isso deve ser solucionado conforme a real necessidade alem de ser avaliado onde a otimização vale mesmo ser empregada e como isso ira prejudicar na legibilidade do codigo sendo assim necessário apenas em grandes necessidades.

A escalabilidade é outro fator muito importante para ser empregada em um projeto e o framework também deve ser escalavel.

Agora gostaria de saber aonde eu posso realmente aprender sobre escalabilidade de frameworks/sistemas e otimização de código , se os livros que eu citei acima são referentes a esse assunto e se suprem toda a necessidade, ou se tudo isso so pode ser aprendido na pratica.

Ainda estou meio confuso em como aprender isso corretamente e aonde achar material de qualidade para pode investir meu tempo ou o que realmente vale a pena aprender.

Agradeço muito a ajuda de vocês e gostaria de saber quais os livros ou tutoriais que vocês me indicam para aprender sobre esse assunto.

Obrigado!

[quote]Item 55 - Otimize criteriosamente
A historia das décadas passadas nos mostram que otimização prematura na verdade é mais propenso a causar danos do que benefícios. O caminho da otimização precoce pode leva-lo a uma solução que ainda não seja rápida, arquiteturalmente ruim e pior de tudo inflexível de difícil evolução. Diante desse fato, não tente criar programas rápidos! Na verdade, foque em criar bons programas, usando todos os conceitos, princípios e abordagem necessários. Se um programa bem arquiteturado não for rápido suficiente, a boa arquitetura já estabelecido permitira que ele seja otimizado. Não pense em problemas de desempenho enquanto estiver projetando uma solução. Quando terminar a codificação, avalie seu desempenho. Se ele for suficientemente rápido, tudo estará resolvido. Caso contrário, localize a fonte de gargalo usando uma ferramenta de gerador de perfil e trabalhe nas partes relevantes. Repita esse processo conforme necessário, avaliando o desempenho após cada alteração até apresentar um tempo satisfatório.[/quote]

Joshua Block no Livro Java Effective - http://fernandofranzini.wordpress.com/2012/08/07/java-efetivo-aprenda-realmente-a-programar-java/

Não conheço livros especificamente sobre isso ( se alguém conhece, por favor , coloque aqui). Vai ter que ser na prática mesmo. Mas ha algumas analises por ai na web comparando a responsividade (thoughtput) e alguns outros pontos entre frameworks. Alguma coisa pode ser avaliada entendo como o framework funciona. Framworks (aplicações em geral) que gravam em session são menos escaláveis que as que não usam session. Pelo simples fato do session ser persistivel e portanto um recurso que “ocupa espaço” consumindo recursos. O request em si não ocupa mais recursos que a propria memória do objeto.
O Effective Java lhe dá um conjunto de boas práticas para escrever bom código java. Entenda como um guia para o programador avançado (se já vez a certificação java, o estilo vai parecer muito parecido). Outro interessante é Java Puzzlers. É um pouco mais desafiador, no estilo de um jogo em que a ideia é ver se vc realmente entende a linguagem. Estes livros são para programadores ( pessoas que escrevem código).
Os livros de design patterns são para vc ganhar vocabulário e uma linguagem base. Isto serve para vc entender e ser entendido. Quando um framework ou alguma especificação façar em Singleton, MVC, Factory, Producer-Comsumer, Observer, etc… vc saber o que isso é e como ajuda a criar sistemas. É bom para vc entender sobre outros sistemas e analisar se o design é bom ou não.

Então, a maioria das coisas vc aprender na prática ou lendo opiniões de outros que já trabalham com a ferramenta. Existem muitas analises que são superficiais e podem enganar. Hoje em dia com tantos frameworks web, ha muita comparação entre eles.
Por exemplo, ha muita gente dizendo que JSF é ruim. Embora seja o padrão EE suportado pelos vendedores de AS e usado como padrão, por exemplo, pelo governo. Não é um framework maduro. A versão 1 e a 2 são diferentes concetualmente pois houve uma redefinição dos ciclos de vida. Isto porque o jsf 1 tinha problemas de compatibilidade com o jsp e a EL. Algo semelhante aconteceu com o JPA 1 que sem API de Criteria se tornou mais um problema que uma solução. Mas ambos funcionam. Tudo depende de quão profundo vc quer ir …