Optimisation des performances Java : huit anti-modèles qui ralentissent votre code

Améliorations des performances grâce à la correction des anti-modèles
Jonathan Vogel a développé une application Java de traitement de commandes qui avait initialement un temps d'exécution de 1 198 ms, traitait 85 000 commandes par seconde, utilisait un peu plus de 1 Go de tas et avait 19 pauses de GC. Après avoir corrigé huit anti-modèles sans changements architecturaux ni mises à jour du JDK, les performances se sont améliorées à 239 ms de temps d'exécution, 419 000 commandes par seconde, 139 Mo de tas et 4 pauses de GC. Cela représente un débit multiplié par 5, une utilisation du tas réduite de 87 % et 79 % de pauses de GC en moins.
Huit anti-modèles de performance Java à corriger
- Concaténation de chaînes dans les boucles - Copie O(n²) due à l'immuabilité
- Itération de flux O(n²) dans les boucles - Parcours de la liste complète par élément
- String.format() dans les chemins critiques - StringBuilder le plus lent, analyse le format à chaque appel
- Autoboxing dans les chemins critiques - Des millions d'objets wrapper jetables
- Exceptions pour le flux de contrôle - fillInStackTrace() parcourt toute la pile d'appels
- Synchronisation trop large - Un verrou devient le goulot d'étranglement
- Recréation d'objets réutilisables - ObjectMapper, DateTimeFormatter, Gson par appel
- Épinglage de threads virtuels (JDK 21-23) - synchronized + E/S bloquantes épingle les porteurs
Exemples détaillés et corrections
1. Concaténation de chaînes dans les boucles
Code problématique :
String report = "";
for (String line : logLines) {
report = report + line + "\n";
}Cela crée une copie O(n²) due à l'immuabilité de String. Les benchmarks JMH de BellSoft montrent que lorsque n est multiplié par 4, la concaténation en boucle ralentit de plus de 7 fois.
Correction :
StringBuilder sb = new StringBuilder();
for (String line : logLines) {
sb.append(line).append("\n");
}
String report = sb.toString();Remarque : Depuis JDK 9, le compilateur optimise la concaténation sur une seule ligne comme "Order: " + id + " total: " + amount, mais cette optimisation ne s'applique pas aux boucles.
2. O(n²) accidentel avec des flux dans les boucles
Code problématique :
for (Order order : orders) {
int hour = order.timestamp().atZone(ZoneId.systemDefault()).getHour();
long countForHour = orders.stream()
.filter(o -> o.timestamp().atZone(ZoneId.systemDefault()).getHour() == hour)
.count();
ordersByHour.put(hour, countForHour);
}Ce motif représentait près de 71 % des échantillons de pile CPU dans l'enregistrement JFR. Avec 10 000 commandes, il effectue 100 millions de comparaisons au lieu d'un seul passage.
Correction :
for (Order order : orders) {
int hour = order.timestamp().atZone(ZoneId.systemDefault()).getHour();
ordersByHour.merge(hour, 1L, Long::sum);
}Cela offre des performances O(n) avec un seul passage. Vous pourriez également utiliser Collectors.groupingBy(... Collectors.counting()) dans un pipeline de flux unique.
Cet article est la partie 1 d'une série de 3 parties sur l'optimisation des performances Java, les parties 2 et 3 arrivant bientôt. La partie 2 examinera les données de profilage derrière ces chiffres, y compris les graphiques en flammes et les méthodes réellement critiques.
📖 Read the full source: HN AI Agents
👀 See Also

Utilisateur de Reddit partage une configuration pratique de Claude pour une assistance IA cohérente en programmation
Un développeur décrit le passage de prompts uniques à des fichiers de contexte séparés (about-me.md, my-voice.md, my-rules.md) et la mise en œuvre d'un flux de travail structuré où Claude lit le contexte, pose des questions, crée des plans, puis exécute des tâches.

Correction de l'invalidation du cache KV de Claude Code avec des backends locaux
Les versions 2.1.36+ de Claude Code injectent des en-têtes de télémétrie dynamique et des mises à jour de l'état git dans chaque requête, rompant la correspondance par préfixe et forçant le retraitement complet des prompts système de plus de 20 000 tokens sur les backends locaux comme llama.cpp. Un correctif de configuration dans ~/.claude/settings.json peut réduire le traitement de plus de 60 secondes à environ 4 secondes.

Structurer les projets de code Claude avec CLAUDE.md, Skills et MCP
Un développeur partage des améliorations de flux de travail pour Claude Code, notamment démarrer en mode planification, maintenir un fichier CLAUDE.md pour la mémoire du projet, créer des Compétences réutilisables pour les tâches récurrentes, et utiliser MCP pour se connecter à des outils externes.

Optimisation d'AutoResearch sur RTX 5090 : Ce qui a échoué et ce qui a fonctionné
Un développeur partage des détails de configuration spécifiques pour exécuter AutoResearch sur une configuration RTX 5090/Blackwell, y compris les approches qui ont échoué, semblaient fonctionnelles mais performaient mal, et la configuration fonctionnelle qui a obtenu des résultats stables avec TOTAL_BATCH_SIZE=2**17 et TIME_BUDGET=1200.