Détails d'optimisation du code
1. Essayez de spécifier que le modificateur final de la classe et de la méthode. Les cours avec des modificateurs finaux avec des modificateurs finaux ne peuvent pas être dérivés. Dans l'API Java Core, il existe de nombreux exemples d'application finale, tels que java.lang.string, et toute la classe est finale. La spécification d'un modificateur final pour une classe peut empêcher la classe d'être héritée, et la spécification d'un modificateur final pour une méthode peut empêcher que la méthode d'être remplacée. Si une classe est spécifiée comme final, toutes les méthodes de cette classe sont finales. Le compilateur Java cherchera des opportunités pour alimenter toutes les méthodes finales. La ligne est d'une grande importance pour améliorer l'efficacité du fonctionnement de Java.
2. Essayez de réutiliser l'utilisation d'objets, en particulier des objets de chaîne. Lorsque la concaténation des chaînes se produit, StringBuilder / StringBuffer doit être utilisée à la place. Étant donné que les machines virtuelles Java ont non seulement besoin de passer du temps à générer des objets, ils peuvent également avoir besoin de passer du temps à collecter et de traiter ces objets à l'avenir, la génération trop d'objets aura un grand impact sur les performances du programme.
3. Utilisez les variables locales pour appeler les méthodes autant que possible. Les paramètres ont passé lorsque les méthodes d'appel et les variables temporaires créées dans l'appel sont stockées plus rapidement sur la pile. D'autres variables, telles que des variables statiques, des variables d'instance, etc., sont créées dans le tas, et la vitesse est plus lente. De plus, comme les variables créées dans la pile sont terminées, ces contenus ont disparu et aucune collection de déchets supplémentaire n'est requise.
4. Fermez le flux dans le temps
Pendant la programmation Java, soyez prudent lorsque vous effectuez des opérations de connexion de base de données et de streaming d'E / S. Après utilisation, fermez-le à temps pour libérer les ressources. Parce que le fonctionnement de ces grands objets provoquera des frais généraux du système et si vous ne faites pas attention, cela entraînera de graves conséquences.
5. Essayez de minimiser le calcul répété des variables, clarifiez un concept. Même s'il n'y a qu'une seule phrase dans la méthode, elle est toujours consommée, y compris la création de trames de pile, la protection du site lors de l'appel de la méthode et de la restauration du site lors de l'appel de la méthode. Ainsi, par exemple, l'opération suivante:
pour (inti = 0; i <list.size (); i ++)
{...} est recommandé pour le remplacer par:
pour (inti = 0, longueur = list.size (); i <longueur; i ++)
{...}
De cette façon, lorsque list.size () est très important, il réduit beaucoup de consommation
6. Essayez d'adopter une stratégie de chargement paresseuse, c'est-à-dire en cas de besoin
7. Utiliser des anomalies avec prudence sera préjudiciable aux performances. Pour lancer une exception, vous devez d'abord créer un nouvel objet. Le constructeur de l'interface jetable appelle la méthode de synchronisation locale nommée FillInstackTrace (). La méthode FILLINSTACKTRACE () vérifie la pile et collecte des informations de trace d'appel. Tant qu'une exception est lancée, la machine virtuelle Java doit ajuster la pile d'appels car un nouvel objet est créé pendant le traitement. Les exceptions ne peuvent être utilisées que pour la gestion des erreurs et ne doivent pas être utilisées pour contrôler le flux du programme.
8. N'utilisez pas d'essayer ... Catch ... dans la boucle, il doit être placé sur la couche la plus externe
Selon les opinions avancées par les internautes, je pense que cela vaut la peine d'être discuté
9. Si vous pouvez estimer la longueur du contenu à ajouter, spécifiez la longueur initiale pour la collection et les classes d'outils implémentées dans un tableau, telles que ArrayList, LinkedLlist, StringBuilder, StringBuffer, Hashmap, HashSet, etc. Prenez StringBuilder comme exemple:
(1) StringBuilder () // par défaut pour allouer 16 caractères (2) StringBuilder (int taille) // par défaut pour allouer 16 caractères (3) StringBuilder (String STR) // par défaut pour allouer 16 caractères + Str.length () des caractères Vous pouvez définir sa capacité d'initialisation via le constructeur de la classe (ici nous référons non seulement à la chaîne de stringbuilder ci-dessus), qui peut améliorer significativement les performances. Par exemple, StringBuilder, la longueur représente le nombre de caractères que le stringbuilder actuel peut maintenir. Étant donné que lorsque StringBuilder atteint sa capacité maximale, elle augmentera sa capacité à 2 fois et en ajoutera 2. Chaque fois que StringBuilder atteindra sa capacité maximale, il devra créer un nouveau tableau de caractères et copier l'ancien contenu de tableau de caractères dans le nouveau tableau de caractères - il s'agit d'une opération très importante. Imaginez simplement, si vous pouvez estimer que 5000 caractères sont stockés dans le tableau de caractères sans spécifier la longueur, la puissance de 2 la plus proche de 5000 est 4096, et les 2 ajoutées à chaque expansion sont quel que soit le 2, alors: alors:
(1) Sur la base de 4096, demandez des réseaux de caractères de taille 8194, qui s'ajoutent à des réseaux de caractères de taille 12290 à la fois. Si vous pouvez spécifier des tableaux de caractères de taille 5000 au début, il économisera plus du double de l'espace (2) copiera les caractères 4096 d'origine dans le nouveau tableau de caractères de cette manière, ce qui gaspillera non seulement l'espace mémoire mais réduira également l'efficacité de l'opération de code. Par conséquent, il n'est pas faux de définir une capacité d'initialisation raisonnable pour les classes de collecte et d'outils implémentées dans le tableau sous-jacent, ce qui apportera des résultats immédiats. Cependant, notez que les collections comme HashMap qui sont implémentées dans les tableaux + listes liées ne doivent pas définir la taille initiale de la même manière que votre taille estimée, car la possibilité d'un seul objet connecté à un tableau est presque 0. Il est recommandé de définir la taille initiale sur N Power de 2. Si vous pouvez estimer qu'il existe 2 000 éléments, le définir sur un nouveau hashmap (128) et New Hashmap (256).
10. Lors de la copie d'une grande quantité de données, utilisez la commande System.ArrayCopy ()
11. Multiplication et opérations de décalage d'utilisation de la division
12. Ne créez pas de références d'objets en continu dans la boucle
Par exemple:
pour (inti = 1; i <= count; i ++) {objet obj = newObject (); }Cette approche entraînera l'exister la référence de l'objet d'objet dans la mémoire. Si le nombre est grand, il consommera la mémoire. Il est recommandé de le changer en:
Objet obj = null; pour (inti = 0; i <= count; i ++) {obj = newObject ();} De cette façon, il n'y a qu'une seule référence d'objet d'objet en mémoire. Chaque fois que le nouvel objet () est utilisé, la référence de l'objet objet pointe vers un objet différent, mais il n'y a qu'un seul objet en mémoire, qui enregistre considérablement l'espace mémoire.
13. En fonction de la prise en compte de l'efficacité et de la vérification des types, le tableau doit être utilisé autant que possible. ArrayList ne doit être utilisé que lorsque la taille du tableau ne peut pas être déterminée.
14. Essayez d'utiliser HashMap, ArrayList et StringBuilder. À moins que le mire ne l'exige, il n'est pas recommandé d'utiliser HashTable, Vector et StringBuffer. Les trois derniers ont des frais généraux de performance en raison de l'utilisation de mécanismes de synchronisation.
15. Ne déclarez pas les tableaux comme finale statique publique
Parce que cela n'a pas de sens, il définit la référence comme finale statique, et le contenu du tableau peut toujours être modifié à volonté. Déclarer le tableau en tant que public est une vulnérabilité de sécurité, ce qui signifie que le tableau peut être modifié par des classes externes
16. Essayez d'utiliser des singletons dans des occasions appropriées. L'utilisation des singletons peut réduire la charge de charge, raccourcir le temps de chargement et améliorer l'efficacité de chargement. Cependant, tous les endroits ne conviennent pas aux singletons. Autrement dit, les singletons sont principalement applicables aux trois aspects suivants:
(1) Contrôler l'utilisation des ressources, contrôler l'accès simultané des ressources par le biais de la synchronisation des threads (2) Contrôler la production d'instances pour atteindre le but d'économiser des ressources (3) contrôler le partage des données et permettre la communication entre plusieurs processus ou threads non liés sans établir des associations directes sans établir des associations directes.
17. Essayez d'éviter d'utiliser des variables statiques à volonté
classe publique A {private statique b b = newb (); } Pour le moment, le cycle de vie de la variable statique B est le même que celui de la classe A. Si la classe A n'est pas désinstallée, l'objet B pointé par référence B résidera en mémoire jusqu'à ce que le programme se termine
18. Effacer les séances qui ne avaient plus besoin à temps. Afin de ne plus ne plus sessions actives, de nombreux serveurs d'application ont un délai d'expiration de session par défaut, généralement 30 minutes. Lorsque le serveur d'applications doit enregistrer plus de sessions, en cas de mémoire insuffisante, le système d'exploitation transférera une partie des données vers le disque. Le serveur d'applications peut également vider certaines sessions inactives sur le disque en fonction de l'algorithme MRU (le plus fréquemment utilisé) et peut même lancer des exceptions de mémoire insuffisantes. Si la session doit être jetée sur le disque, elle doit d'abord être sérialisée. Dans les grappes à grande échelle, le sérialisation des objets coûte cher. Par conséquent, lorsque la session n'est plus nécessaire, la méthode invalidate () de httpSession doit être appelée à temps pour effacer la session.
19. Pour les collections qui implémentent les interfaces RandomAccess, telles que ArrayList, vous devez utiliser la boucle la plus courante au lieu de Foreach Loop pour traverser ceci est recommandé par JDK aux utilisateurs. L'explication par l'API JDK de l'interface RandomAccess est: l'implémentation de l'interface RandomAccess est utilisée pour indiquer qu'il prend en charge un accès aléatoire rapide. L'objectif principal de cette interface est de permettre aux algorithmes généraux de modifier leur comportement, afin qu'il puisse fournir de bonnes performances lorsqu'il est appliqué à des listes d'accès aléatoires ou continues. L'expérience pratique montre que si les instances de classe qui implémentent l'interface aléatoire sont accessibles au hasard, l'efficacité de l'utilisation d'ordinaires pour les boucles sera plus élevée que celle de l'utilisation de boucles foreach; Inversement, s'il est accessible séquentiellement, il sera plus efficace d'utiliser Iterator. Vous pouvez utiliser des codes similaires à ce qui suit pour porter des jugements:
if (list instanceOfrandomAccess) {for (inti = 0; i <list.size (); i ++) {}} else {iterator <?> iterator = list.iterable (); while (iterator.hasnext ()) {iterator.next ()}} Le principe de mise en œuvre sous-jacent de la boucle foreach est l'itérateur, de sorte que la seconde moitié de la phrase "à son tour, si elle est accessible séquentiellement, l'utilisation de l'itérateur sera plus efficace" signifie que les instances de classe accessibles séquentiellement et utilisent la boucle ForEach pour traverser.
20. L'utilisation de blocs de code synchronisés au lieu des méthodes de synchronisation a été expliquée très clairement dans l'article de bloc de méthode de verrouillage synchronisé dans un module multi-thread. À moins qu'il ne puisse être déterminé que la méthode entière doit être synchronisée, essayez d'utiliser des blocs de code synchronisés pour éviter de synchroniser les codes qui n'ont pas besoin d'être synchronisés, ce qui affecte l'efficacité d'exécution du code.
21. Déclarez les constantes comme finales statiques et nommez-les en capital afin que ces contenus puissent être placés dans le pool constant pendant la compilation, en évitant le calcul des valeurs constantes générées pendant l'exécution. De plus, le nom du nom d'une constante en capital peut également faciliter la distinction entre les constantes et les variables
22. Ne créez pas de quelques objets inutilisés, n'importez pas de classes inutilisées
Cela n'a aucun sens. Si "la valeur de la variable locale I n'est pas utilisée" et "L'importation java.util n'est jamais utilisée" apparaître dans le code, veuillez supprimer ces contenus inutiles
23. Évitez d'utiliser la réflexion pendant le fonctionnement du programme. Pour plus d'informations, veuillez consulter la réflexion. La réflexion est une fonction très puissante fournie par Java aux utilisateurs. Des fonctions puissantes signifient souvent une faible efficacité. Il n'est pas recommandé d'utiliser le mécanisme de réflexion dans le processus d'exécution du programme, en particulier la méthode d'appel de la méthode. S'il est effectivement nécessaire, une approche suggestive consiste à instancier un objet par la réflexion et à la mettre en mémoire lorsque le projet est démarré - l'utilisateur ne se soucie que de la vitesse de réponse la plus rapide lors de l'interaction avec le pair et ne se soucie pas du temps qu'il faut pour que le projet de homologue commence.
24. Utilisez le pool de connexions de la base de données et le pool de threads, les deux pools, sont utilisés pour réutiliser des objets. Les premiers peuvent éviter l'ouverture et la fermeture fréquentes des connexions, et les seconds peuvent éviter la création et la destruction fréquentes des fils.
25. Utilisez des flux d'entrée et de sortie tamponnés pour les opérations IO
Streams d'entrée et de sortie tamponnés, à savoir BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream, qui peut considérablement améliorer l'efficacité IO
26. Utilisez ArrayList pour des scènes avec une insertion plus séquentielle et un accès aléatoire, et utilisez LinkedList pour des scènes avec plus de suppression d'éléments et d'insertion intermédiaire.
Ceci est connu en comprenant les principes d'ArrayList et de LinkedList
27. Ne laissez pas trop de paramètres formels dans la méthode publique
La méthode publique est une méthode fournie au monde extérieur. Si vous donnez à ces méthodes trop de paramètres formels, il existe deux principaux inconvénients:
1) Violation de l'idée de programmation orientée objet. Java souligne que tout est un objet. Trop de paramètres formels ne sont pas conformes à l'idée de programmation orientée objet.
2) Trop de paramètres entraîneront inévitablement une augmentation de la probabilité d'erreur dans l'appel de la méthode. Quant au nombre de «trop», référence à, 3 ou 4. Par exemple, nous utilisons JDBC pour écrire une méthode InsertStudentinfo. Il y a 10 champs d'information des étudiants à insérer dans la table des étudiants. Ces 10 paramètres peuvent être encapsulés dans une classe d'entité comme paramètres formels de la méthode d'insertion.
28. Lors de l'écriture de variables de chaîne et de constantes de chaîne égales, c'est une astuce relativement courante pour écrire des constantes de chaîne devant. S'il y a le code suivant:
String str = "123"; if (str.equals ("123")) {...} Il est recommandé de le modifier à:
String str = "123"; if ("123" .equals (str)) {...} Cela peut principalement éviter les exceptions du pointeur nul
32. Ne forcez pas la transformation vers le bas des types de données de base au-delà de la portée
33. Convertir un type de données de base en une chaîne. Le type de données de base.toString () est le moyen le plus rapide, suivi de String.Valueof (données), et Data + "Le moyen le plus lent de convertir un type de données de base en trois façons. J'ai un type entier Data I, qui peut utiliser I.ToString (), String.Valueof (i), i +" ". Quelle est la efficacité des trois méthodes? Voir un test:
publicStatic void main (String [] args) {intloopTime = 50000; Entier i = 0; longstarttime = System.CurrentTimemillis (); pour (intj = 0; j <looptime; j ++) {String str = string.valueof (i); } System.out.println ("string.valueof ():" + (System.currentTimemillis () - starttime) + "ms"); startTime = System.CurrentTimemillis (); pour (intj = 0; j <looptime; j ++) {String str = i.toString (); } System.out.println ("Integer.ToString ():" + (System.currentTimemillis () - starttime) + "MS"); startTime = System.CurrentTimemillis (); pour (intj = 0; j <looptime; j ++) {String str = i + ""; } System.out.println ("i + /" / ":" + (System.currentTimemillis () - starttime) + "ms");}Le résultat en cours est:
String.ValueOf (): 11msInteger.ToString (): 5ms + "": 25ms
Par conséquent, lorsque vous convertissez un type de données de base en chaîne à l'avenir, vous devez donner la priorité à l'utilisation de la méthode toString (). Quant à pourquoi, c'est très simple:
1. La méthode String.ValueOf () est appelée la méthode Integer.ToString () en bas, mais il fera un court jugement avant d'appeler.
2. Je ne parlerai pas de la méthode Integer.ToString (), je l'appellerai directement.
3. La couche inférieure de I + "" utilise StringBuilder pour l'implémenter. Utilisez d'abord la méthode APPEND pour l'épisser, puis utilisez la méthode toString () pour obtenir la chaîne. C'est évidemment le 2 le plus rapide, le 1 le plus rapide et le 3 le plus lent.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.