Ao escrever algo que cria muitos (1000s) de objetos pequenos com frequência, você deve minimizá-lo para obter desempenho? Especialmente se você não souber em qual sistema ele será executado, de computadores de mesa de ponta a ponta ou até móveis. Para dispositivos móveis, ouvi dizer que a criação de muitos objetos dificulta bastante o desempenho, embora eu não saiba o quanto isso é verdade.
Eu tenho um exemplo que mostra bem essa ideia. Em um programa gráfico, digamos que exista um método usado para todos os desenhos idealmente chamados drawPixel(Point)
. Pode haver milhares de pontos criados e isso pode ser repetido com frequência, como em um jogo em que poderia ser chamado mais de 60 vezes por segundo. Como alternativa, drawPixel(int x, int y)
poderia ser usado para minimizar a criação de muitos objetos Point.
Em um design orientado a objetos, acho que usar o Point seria preferido. No entanto, o uso de tipos primitivos pode aumentar o desempenho. O ganho de desempenho pode ser insignificante na maioria dos casos, mas não tenho certeza sobre coisas como máquinas móveis ou mais antigas. Qual é o ganho de desempenho ao fazer algo assim e é algo que deve ser levado em consideração?
fonte
System.getProperty("java.version")
(ou "java.vm.version") é um ponto de partida.Respostas:
Em geral, não , você não deve evitar criar objetos por medo de perda de desempenho. Há várias razões para isso.
Dito isto, há lugares em que transformar algo em um objeto não faz sentido, para começar. Passar duas coordenadas para uma rotina de desenho pode ser o caso: o par de coordenadas não tem existência independente, não tem identidade, é usado apenas uma vez e depois descartado imediatamente, etc.
Se for esse o caso, com certeza, vá em frente e passe dois
int
s em vez de envolvê-los em um objeto. O ponto de POO não é que tudo deve ser um objeto. A questão é que os objetos facilitam o desenvolvimento em locais onde são a solução natural para um problema de representação de dados. Não evite objetos onde eles fazem sentido - não os apresente onde não fazem.fonte
Ao contemplar os impactos no desempenho antes de escrever o código, você deve assumir que não sabe o que está fazendo.
Há uma sobrecarga de espaço muito pequena para objetos em java versus primitivos. Quanto menores os objetos, maior será a porcentagem de sobrecarga. No entanto, aprendi há muito tempo que coisas que dobram n não são nada em comparação com coisas que multiplicam n por n.
Portanto, embora sim, você pode organizar um sistema que tenha metade do tamanho ou até um quarto, por favor, pergunte-se por que realmente se importa. Soluções complicadas para esse problema não serão bem recebidas. Particularmente porque mergulhar nesse código será confuso. Programadores confusos escrevem código incorreto. Eles escrevem n vezes n código que deve ser n log n código. E eles demoram mais para fazer isso.
Agora, se você puder me poupar espaço com algum truque que caiba em uma caixa legal, não preciso olhar para dentro na maior parte do tempo para conversar. Se for uma caixa, eu posso trocar por outra, quando essa caixa funcionar melhor, posso até pagar por ela.
fonte
No ajuste de desempenho que fiz ( exemplo ), é muito fácil o gerenciamento de memória ser o principal culpado. Não me importo com o quão loucamente eles ajustaram o novo operador e o coletor de lixo, o cálculo mais rápido é o cálculo. Portanto, se eu descobrir que o gerenciador de memória leva uma boa porcentagem de tempo e não consigo evitar a criação de objetos , encontro uma maneira de reutilizá-los, em vez de criar constantemente novos.
Só o faço se tiver que fazer objetos. Para gráficos, geralmente não. IMHO, os gráficos devem ser desenhados , não construídos . Claro, você poderia dizer que uma imagem consiste em pontos, linhas que os conectam, polígonos, texto e assim por diante. Isso não significa que você não tem alternativa para criar objetos com eles antes de desenhá- los. Eu apenas os desenhei.
Existe um método Paint. Eu substituo isso, desenhe tudo em um bitmap e, em seguida, bloqueio a transferência para a tela. Parece instantâneo. Para entrada do mouse, existem métodos para substituir, detectar clique, arrastar, o que for.
OOP é uma boa ideia por certos motivos. Esses motivos não se aplicam a todas as situações.
fonte
Vá em frente e use pequenas alocações. Os gerenciadores de memória modernos, particularmente o gerenciador de objetos Java altamente otimizado, são extremamente eficientes. Salve a otimização de desempenho principal para um programa de trabalho.
É extremamente provável que o desempenho geral seja adequado. Se você achar que não é esse o caso, então, e somente então , analise o desempenho do código. Em uma longa carreira de desenvolvimento de software, aprendi que os gargalos quase nunca estão onde você espera.
Certa vez, um membro da equipe passou vários dias tornando a pesquisa de membro do objeto 20x mais rápida. Sucesso! No entanto, a melhor aceleração geral no uso real foi medida em centésimos de um por cento. A alteração foi imediatamente restaurada, pois a aceleração exigia alocações de memória maiores por membro.
fonte
É simples: se você precisar de 1000 objetos pequenos, crie 1000 objetos pequenos e não se preocupe. Se você precisar de 100 objetos pequenos, criar 1000 objetos pequenos é estúpido - crie os que você precisa e não mais.
Se você está preocupado com o desempenho (e se também não está preocupado com o desempenho), deve ter qualquer funcionalidade escrita uma vez em um só lugar, o que torna todo o código mais simples e fácil de entender. Então, se você tiver um problema de desempenho, a medição poderá mostrar que existe um local onde o problema ocorre, o que facilita as coisas e apenas um local em que você precisa alterá-lo. Ou a medição mostra que este lugar não causa problemas, então está pronto.
fonte