Maison >Java >javaDidacticiel >Résumé de l'optimisation des performances du code de développement Java
L'optimisation du code peut sembler inutile à certaines personnes. Mais je pense que vous devriez faire de votre mieux pour développer de bonnes habitudes pendant le processus de développement. Si vous accumulez de petits points d'optimisation un par un, vous constaterez certainement une amélioration significative de l'efficacité. . D'accord, permettez-moi de partager avec vous le résumé que je vois habituellement utilisé.
Objectifs de l'optimisation du code
1 Réduire la taille du code
2 Améliorer les performances de l'ensemble du système Efficacité opérationnelle
Optimisation des détails du code
1 Essayez de spécifier le modificateur final de la classe et méthode
Les classes avec modification finale ne sont pas dérivées. Dans l'API principale Java, il existe de nombreux exemples d'utilisation de final, tels que java.lang.String. La classe entière est finale. La spécification du modificateur final pour une classe peut empêcher l'héritage de la classe, et la spécification de final pour une méthode peut le faire. empêcher que la méthode ne soit héritée a été réécrite. Si vous spécifiez une classe comme finale, toutes les méthodes de la classe sont finales. Le compilateur Java recherchera des opportunités pour intégrer toutes les méthodes finales. L'intégration joue un rôle important dans l'amélioration de l'efficacité de l'exécution de Java. Pour plus de détails, voir Optimisation de l'exécution Java. Cela peut améliorer les performances de 50 % en moyenne.
2 Essayez de réutiliser les objets
Spécialement pour l'utilisation d'objets String, StringBuilder/ doit être utilisé lorsque la chaîne des connexions se produisent à la place. Étant donné que la machine virtuelle Java ne passe pas seulement du temps à générer des objets, elle devra peut-être également consacrer du temps à la collecte et au traitement de ces objets à l'avenir. Par conséquent, générer trop d'objets aura un impact important sur les performances du programme.
3 Utiliser des objets locaux autant que possible
Paramètres passés lors de l'appel d'une méthode et variables temporaires créées lors de l'appel Ils sont toutes enregistrées dans la pile et sont plus rapides. D'autres variables, telles que les variables statiques et les variables d'instance, sont créées dans le tas et sont plus lentes. De plus, le contenu des variables créées dans la pile disparaît à la fin de la méthode et aucun garbage collection supplémentaire n'est requis.
4 Fermez le flux rapidement
Pendant le processus de programmation Java, assurez-vous d'effectuer des connexions à la base de données et I/ O opérations de flux Veillez à le fermer rapidement après utilisation pour libérer des ressources. Étant donné que l’exploitation de ces gros objets entraînera une surcharge système importante, un peu de négligence entraînera de graves conséquences.
5 Essayer de réduire les calculs répétés de variables
Clairer un concept, l'appel à une méthode, même dans une méthode Il n'y a qu'une seule instruction, qui est également consommée, notamment la création d'un cadre de pile, la protection de la scène lors de l'appel de la méthode, la restauration de la scène lorsque la méthode est appelée, etc. Ainsi par exemple, il est recommandé de remplacer l'opération suivante :
for (int i = 0; i < list.size(); i++) {...}
par :
for (int i = 0, int length = list.size(); i < length; i++) {...}
De cette façon, lorsque list.size() est très grand, beaucoup de la consommation est réduite
6 Essayez d'adopter une stratégie de chargement paresseux, c'est-à-dire de créer
uniquement en cas de besoin :
String str = "aaa";if (i == 1) { list.add(str); }
. Il est recommandé de le remplacer par :
if (i == 1) {String str = "aaa"; list.add(str); }
7 Utilisez les exceptions avec prudence
Les exceptions nuisent aux performances. Pour lever une exception, vous devez d'abord créer un nouvel objet. Le constructeur de l'interface Throwable appelle la méthode de synchronisation locale nommée fillInStackTrace(). La méthode fillInStackTrace() vérifie la pile et collecte les informations de trace d'appel. Chaque fois qu'une exception est levée, la machine virtuelle Java doit ajuster la pile d'appels car un nouvel objet est créé pendant le traitement. Les exceptions ne doivent être utilisées que pour la gestion des erreurs et ne doivent pas être utilisées pour contrôler le déroulement du programme.
8 N'utilisez pas try...catch... dans une boucle, il doit être placé à l'extérieur
à moins qu'il est absolument nécessaire. Si vous écrivez ceci sans aucune raison, tant que votre leader est plus âgé et souffre d'un trouble obsessionnel-compulsif, il vous grondera probablement pour avoir écrit un tel code poubelle
9 Si la longueur du contenu à ajouter peut être estimée, spécifiez la longueur initiale pour les collections sous-jacentes et les classes d'outils implémentées dans le tableau
telles que ArrayList, LinkedLlist, StringBuilder, StringBuffer , HashMap , HashSet, etc., en prenant StringBuilder comme exemple :
(1) StringBuilder() // Alloue 16 caractères d'espace par défaut
(2) StringBuilder (int size) // L'allocation par défaut est la taille de l'espace de caractères
(3) StringBuilder(String str) // L'allocation par défaut est de 16 caractères str.length() espace de caractères
Vous pouvez définir sa capacité d'initialisation via la classe (il ne s'agit pas seulement ici du StringBuilder ci-dessus), ce qui peut améliorer considérablement les performances. Par exemple, StringBuilder, la longueur représente le nombre de caractères que le StringBuilder actuel peut contenir. Parce que lorsque StringBuilder atteint sa capacité maximale, il augmentera sa capacité à 2 fois sa capacité actuelle plus 2. Chaque fois que StringBuilder atteint sa capacité maximale, il doit créer un nouveau tableau de caractères, puis remplacer les anciens caractères par le contenu du tableau. copié dans un nouveau tableau de caractères - il s'agit d'une opération très gourmande en performances. Imaginez, si vous pouvez estimer qu'environ 5 000 caractères seront stockés dans le tableau de caractères sans spécifier la longueur, la puissance la plus proche de 2 à 5 000 est 4096, et 2 seront ajoutés pour chaque extension, alors :
(1) Sur la base de 4096, postulez pour 8194 tableaux de caractères, ce qui revient à demander 12290 tableaux de caractères à la fois. Si vous pouvez spécifier un tableau de caractères de 5000 tailles au début, Cela permet d'économiser plus du double de l'espace
(2) Copiez les 4096 caractères d'origine dans le nouveau tableau de caractères
这样,既浪费内存空间又降低代码运行效率。所以,给底层以数组实现的集合、工具类设置一个合理的初始化容量是错不了的,这会带来立竿见影的效果。但是,注意,像HashMap这种是以数组+链表实现的集合,别把初始大小和你估计的大小设置得一样,因为一个table上只连接一个对象的可能性几乎为0。初始大小建议设置为2的N次幂,如果能估计到有2000个元素,设置成new HashMap(128)、new HashMap(256)都可以。
10 当复制大量数据时,使用 System.arraycopy() 命令
11 乘法和除法使用移位操作
例如:
for (val = 0; val < 100000; val += 5) { a = val * 8; b = val / 2; }
用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的,因此建议修改为:
for (val = 0; val < 100000; val += 5) { a = val << 3; b = val >> 1; }
移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。
12 循环内不要不断创建对象引用
例如:
for (int i = 1; i <= count; i++) {Object obj = new Object(); }
这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
这样的话,内存中只有一份Object对象引用,每次new Object()的时候,Object对象引用指向不同的Object罢了,但是内存中只有一份,这样就大大节省了内存空间了。
13基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList
14尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销
15 不要将数组声明为 public static final
因为这毫无意义,这样只是定义了引用为 static final ,数组的内容还是可以随意改变的,将数组声明为 public 更是一个安全漏洞,这意味着这个数组可以被外部类所改变
16 尽量在合适的场合使用单例
使用单例可以减轻加载的负担、缩短加载的时间、提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:
(1)控制资源的使用,通过线程同步来控制资源的并发访问
(2)控制实例的产生,以达到节约资源的目的
(3)控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信
17 尽量避免随意使用静态变量
要知道,当某个对象被定义为 static 的变量所引用,那么 gc 通常是不会回收这个对象所占有的堆内存的,如:
public class A{private static B b = new B(); }
以上就是Java开发代码性能优化总结的内容,更多相关内容请关注PHP中文网(www.php.cn)!