Detalhes da otimização de código
1. Tente especificar que o modificador final da classe e do método. Classes com modificadores finais com modificadores finais não podem ser derivados. Na API do Java Core, há muitos exemplos de aplicação final, como java.lang.string, e toda a classe é final. Especificar um modificador final para uma classe pode impedir que a classe seja herdada e a especificação de um modificador final para um método pode impedir que o método seja substituído. Se uma classe for especificada como final, todos os métodos dessa classe serão finais. O compilador Java procurará oportunidades para incluir todos os métodos finais. O inline é de grande importância para melhorar a eficiência da operação do Java.
2. Tente reutilizar o uso de objetos, especialmente objetos de string. Quando ocorre concatenação da String, o StringBuilder/StringBuffer deve ser usado. Como as máquinas virtuais Java não apenas precisam gastar tempo gerando objetos, mas também podem precisar gastar tempo coletando e processando esses objetos no futuro, gerando muitos objetos terão um grande impacto no desempenho do programa.
3. Use variáveis locais para chamar métodos o máximo possível. Os parâmetros foram aprovados ao chamar métodos e as variáveis temporárias criadas na chamada são armazenadas na pilha mais rapidamente. Outras variáveis, como variáveis estáticas, variáveis de instância, etc., são criadas na pilha e a velocidade é mais lenta. Além disso, como as variáveis criadas na pilha estão finalizadas, esses conteúdos desaparecem e nenhuma coleta adicional de lixo é necessária.
4. Feche o fluxo no tempo
Durante a programação Java, tenha cuidado ao executar a conexão com o banco de dados e as operações de streaming de E/S. Após o uso, feche -o a tempo de liberar recursos. Como a operação desses objetos grandes causará grandes despesas gerais do sistema e, se você não tomar cuidado, isso levará a sérias conseqüências.
5. Tente minimizar o cálculo repetido de variáveis, esclarecer um conceito. Mesmo se houver apenas uma frase no método, ela ainda é consumida, incluindo a criação de quadros de pilha, a proteção do site ao chamar o método e restaurar o site ao chamar o método. Por exemplo, a seguinte operação:
for (inti = 0; i <list.size (); i ++)
{...} é recomendado para substituí -lo por:
for (inti = 0, comprimento = list.size (); i <comprimento; i ++)
{...}
Dessa forma, quando list.size () é muito grande, reduz muito consumo
6. Tente adotar uma estratégia de carregamento preguiçosa, ou seja, crie -a quando necessário
7. Use anormalidades com cautela será prejudicial ao desempenho. Para fazer uma exceção, você deve primeiro criar um novo objeto. O construtor da interface jogável chama o método de sincronização local chamado FillInstackTrace (). O método FillInstackTrace () verifica a pilha e coleta informações de rastreamento de chamadas. Enquanto uma exceção for lançada, a máquina virtual Java deve ajustar a pilha de chamadas porque um novo objeto é criado durante o processamento. Exceções só podem ser usadas para manuseio de erros e não devem ser usadas para controlar o fluxo do programa.
8. Não use tente ... pegar ... no loop, deve ser colocado na camada mais externa
De acordo com as opiniões apresentadas pelos internautas, acho que vale a pena discutir
9. Se você puder estimar o comprimento do conteúdo a ser adicionado, especifique o comprimento inicial para as classes de coleta e ferramentas implementadas em uma matriz, como ArrayList, Linkedllist, StringBuilder, StringBuffer, Hashmap, Hashset, etc. Tome StringBuilder como exemplo:
(1) StringBuilder () // Padrão de alocar 16 caracteres (2) StringBuilder (Int Size) // Padrão para alocar 16 caracteres (3) Stringbuilder (String str) // Padrão para alocar 16 caracteres + str.length () Space de caracteres), você pode definir sua capacidade de inicialização acima do construtor que pode ser um dos que se referem apenas a Str.Lengen. Por exemplo, o StringBuilder, o comprimento representa o número de caracteres que o atual StringBuilder pode manter. Como quando o StringBuilder atinge sua capacidade máxima, ele aumentará sua capacidade para 2 vezes e adiciona 2. Sempre que o StringBuilder atingir sua capacidade máxima, terá que criar uma nova matriz de caracteres e copiar o conteúdo da matriz antiga para a nova matriz de caracteres - esta é uma operação muito consumida por desempenho. Imagine, se você puder estimar que 5000 caracteres são armazenados na matriz de caracteres sem especificar o comprimento, o poder de 2 mais próximo de 5000 é 4096, e o 2 adicionado a cada expansão é independentemente dos 2, então:
(1) Com base no 4096, solicite matrizes de caracteres de 8194, que somam as matrizes de caracteres de 12290 de tamanho de uma só vez. Se você puder especificar matrizes de caracteres de 5000 de tamanho 5.000 no início, ele economizará mais do que o dobro do espaço (2) copiar os caracteres 4096 originais na nova matriz de caracteres dessa maneira, que não apenas desperdiçará o espaço de memória, mas também reduzirá a eficiência da operação do código. Portanto, não é errado definir uma capacidade de inicialização razoável para as classes de coleta e ferramentas implementadas na matriz subjacente, que trará resultados imediatos. No entanto, observe que coleções como o hashmap que são implementadas nas matrizes + listas vinculadas não devem definir o tamanho inicial do mesmo tamanho, porque a possibilidade de apenas um objeto conectado a uma tabela é quase 0. É recomendável definir o tamanho inicial para N POWER 2.
10. Ao copiar uma grande quantidade de dados, use o comando System.arrayCopy ()
11. Multiplicação e Divisão Use operações de turno
12. Não crie referências de objeto continuamente no loop
Por exemplo:
for (inti = 1; i <= count; i ++) {objeto obj = newObject (); }Essa abordagem fará com que a referência do objeto de contagem exista na memória. Se a contagem for grande, ela consumirá memória. É recomendável alterá -lo para:
Objeto obj = null; para (inti = 0; i <= count; i ++) {obj = newObject ();} Dessa maneira, existe apenas um objeto de referência de objeto na memória. Toda vez que o novo objeto () é usado, o objeto de objeto aponta para um objeto diferente, mas existe apenas um objeto na memória, que salva muito o espaço de memória.
13. Com base na consideração da eficiência e da verificação do tipo, a matriz deve ser usada o máximo possível. O Arraylist deve ser usado apenas quando o tamanho da matriz não puder ser determinado.
14. Tente usar o HashMap, ArrayList e Stringbuilder. A menos que a segura de threads exija, não é recomendável usar hashtable, vetor e stringbuffer. Os três últimos têm sobrecarga de desempenho devido ao uso de mecanismos de sincronização.
15. Não declare matrizes como final estático público
Como isso não faz sentido, ele define apenas a referência como final estática, e o conteúdo da matriz ainda pode ser alterado à vontade. Declarar a matriz como público é uma vulnerabilidade de segurança, o que significa que a matriz pode ser alterada por classes externas
16. Tente usar singletons em ocasiões adequadas. O uso de singletons pode reduzir a carga de carga, reduzir o tempo de carregamento e melhorar a eficiência de carregamento. No entanto, nem todos os lugares são adequados para singletons. Simplificando, os singletons são aplicáveis principalmente aos três aspectos a seguir:
(1) Controle o uso de recursos, controlar o acesso simultâneo dos recursos por meio da sincronização de threads (2) controlar a geração de instâncias para alcançar o objetivo de salvar recursos (3) controlar o compartilhamento de dados e permitir a comunicação entre vários processos não relacionados ou threads sem estabelecer associações diretas sem estabelecer associações diretas.
17. Tente evitar o uso de variáveis estáticas à vontade
public classe A {private static b b = newb (); } Neste momento, o ciclo de vida da variável estática B é o mesmo da classe A. Se a classe A não for desinstalada, o objeto B apontado pela referência B residirá na memória até que o programa termine
18. Clear não é mais necessário sessões no tempo. Para limpar as sessões não mais ativas, muitos servidores de aplicativos têm um tempo limite de sessão padrão, geralmente 30 minutos. Quando o servidor de aplicativos precisa salvar mais sessões, se houver memória insuficiente, o sistema operacional transferirá parte dos dados para o disco. O servidor de aplicativos também pode despejar algumas sessões inativas em disco de acordo com o algoritmo MRU (mais frequentemente usado recentemente) e pode até lançar exceções insuficientes de memória. Se a sessão for despejada no disco, ela deve ser serializada primeiro. Em aglomerados em larga escala, os objetos serializados são caros. Portanto, quando a sessão não for mais necessária, o método Invalidate () de HttpSession deve ser chamado a tempo para limpar a sessão.
19. Para coleções que implementam interfaces aleatórias, como a ArrayList, você deve usar o mais comum para loop em vez de foreach loop para atravessar isso é recomendado pelo JDK aos usuários. A explicação da API da JDK sobre a interface RandomAccess é: implementar a interface RandomAccess é usada para indicar que ela suporta acesso aleatório rápido. O principal objetivo dessa interface é permitir que os algoritmos gerais alterem seu comportamento, para que possa fornecer um bom desempenho quando aplicado a listas de acesso aleatório ou contínuo. A experiência prática mostra que, se as instâncias de classe que implementam a interface aleatória forem acessadas aleatoriamente, a eficiência do uso de loops ordinárias será maior que a de usar loops foreach; Por outro lado, se acessado sequencialmente, será mais eficiente usar o iterador. Você pode usar códigos semelhantes aos seguintes para fazer julgamentos:
if (list, instanceofrandomaccess) {for (inti = 0; i <list.size (); i ++) {}} else {iterator <?> iterator = list.iterable (); while (iterator.hasnext ()) {iterator.Next ()}} O princípio de implementação subjacente do Foreach Loop é o iterador; portanto, a segunda metade da frase "por sua vez, se for acessada sequencialmente, o uso do iterador será mais eficiente" significa que as instâncias de classe são acessadas sequencialmente e usarão o loop foreach para atravessar.
20. O uso de blocos de código sincronizado em vez de métodos de sincronização foi explicado com muita clareza no artigo de bloco de métodos de bloqueio sincronizado no módulo multitreado. A menos que possa ser determinado que todo o método precisa ser sincronizado, tente usar blocos de código sincronizado para evitar sincronizar os códigos que não precisam ser sincronizados, o que afeta a eficiência da execução do código.
21. Declare as constantes como final estático e nomeie -as em capital para que esses conteúdos possam ser colocados no pool constante durante a compilação, evitando o cálculo dos valores constantes gerados durante o tempo de execução. Além disso, nomear o nome de uma constante em capital também pode facilitar a distinção entre constantes e variáveis
22. Não crie alguns objetos não utilizados, não importe algumas classes não utilizadas
Isso não faz sentido. Se "o valor da variável local I não é usado" e "o importe java.util nunca é usado" aparecer no código, exclua esses conteúdos inúteis
23. Evite usar a reflexão durante a operação do programa. Para mais informações, consulte a reflexão. A reflexão é uma função muito poderosa fornecida pelo Java aos usuários. Funções poderosas geralmente significam baixa eficiência. Não é recomendável usar o mecanismo de reflexão no processo de execução do programa, especialmente o método de invasão do método. Se for realmente necessário, uma abordagem sugestiva é instanciar um objeto através da reflexão e colocá -lo na memória quando o projeto é iniciado - o usuário só se preocupa com a velocidade de resposta mais rápida ao interagir com o par e não se importa com quanto tempo leva para o início do projeto de pares.
24. Use o pool de conexão do banco de dados e o pool de threads, ambos os pools, são usados para reutilizar objetos. O primeiro pode evitar a abertura e o fechamento frequentes das conexões, e o último pode evitar a criação e destruição frequentes de fios.
25. Use fluxos de entrada e saída em buffer para operações de IO
Os fluxos de entrada e saída em buffer, nomeadamente BufferredReader, BufferWriter, BufferErnputStream, BufferedOutputStream, que podem melhorar bastante a eficiência de IO
26. Use Arraylist para cenas com mais inserção seqüencial e acesso aleatório e use o LinkedList para cenas com mais exclusão de elementos e inserção intermediária.
Isso é conhecido pela compreensão dos princípios da ArrayList e LinkedList
27. Não deixe muitos parâmetros formais no método público
O método público é um método fornecido ao mundo exterior. Se você fornecer a esses métodos muitos parâmetros formais, há duas principais desvantagens:
1) Violar a idéia de programação orientada a objetos. Java enfatiza que tudo é um objeto. Muitos parâmetros formais não estão alinhados com a ideia de programação orientada a objetos.
2) Muitos parâmetros inevitavelmente levarão a um aumento na probabilidade de erro na chamada do método. Quanto a quantos "demais" se referem, 3 ou 4. Por exemplo, usamos o JDBC para escrever um método InsertStudentInfo. Existem 10 campos de informação do aluno a serem inseridos na tabela do aluno. Esses 10 parâmetros podem ser encapsulados em uma classe de entidade como parâmetros formais do método de inserção.
28. Ao escrever variáveis de string e constantes de string são iguais, é um truque relativamente comum escrever constantes de string na frente. Se houver o seguinte código:
String str = "123"; if (str.equals ("123")) {...} Recomenda -se modificá -lo para:
String str = "123"; if ("123" .equals (str)) {...} Isso pode evitar principalmente exceções nulas de ponteiro
32. Não force a transformação descendente de tipos de dados básicos além do escopo
33. Converta um tipo de dados básico em uma string. O tipo de dados básico.ToString () é a maneira mais rápida, seguida por String.ValueOf (Data) e Data + "A maneira mais lenta de converter um tipo de dados básico em três maneiras. Eu tenho um tipo de número inteiro I, que pode usar i.ToString (), String.Valueof (i), i +" ". Como eficiente são os três métodos?
publicstatic void main (string [] args) {Intlooptime = 50000; Número inteiro i = 0; LongstartTime = System.CurrentTimemillis (); for (intj = 0; j <looptime; j ++) {string str = string.valueof (i); } System.out.println ("string.valueof ():" + (system.currenttimemillis () - starttime) + "ms"); startTime = system.currenttimemillis (); for (intj = 0; j <looptime; j ++) {string str = i.toString (); } System.out.println ("Integer.toString ():" + (System.CurrentTimeMillis () - StartTime) + "MS"); startTime = system.currenttimemillis (); for (intj = 0; j <looptime; j ++) {string str = i+""; } System.out.println ("i + /" /":" + (System.currenttimemillis () - starttime) + "ms");}O resultado em execução é:
String.valueof (): 11minteger.toString (): 5ms + "": 25ms
Portanto, quando você converte um tipo de dados básico em string no futuro, você deve priorizar o uso do método ToString (). Quanto ao porquê, é muito simples:
1. O método String.ValueOf () é chamado de método inteiro.toString () na parte inferior, mas fará um breve julgamento antes de ligar.
2. Não vou falar sobre o método integer.toString (), chamarei diretamente.
3. A camada inferior de I + "" usa StringBuilder para implementá -lo. Primeiro, use o método Apênd para secá -lo e, em seguida, use o método ToString () para obter a string. É obviamente o 2 mais rápido, o 1 mais rápido e o 3 mais lento.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.