1 points par GN⁺ 2025-03-19 | 1 commentaires | Partager sur WhatsApp
  • En compilant soi-même le paquet source de jq fourni par Ubuntu, il est possible d’améliorer les performances jusqu’à 90 %
  • Les performances sont maximisées en améliorant le compilateur, les drapeaux d’optimisation et l’allocateur mémoire

Configuration

  • jq est utilisé pour traiter des fichiers GeoJSON au format JSON
    • Exécution d’une requête qui affiche le nom de la ville de toutes les parcelles dont la valeur dépasse un certain seuil dans la carte parcellaire de l’Alameda County Assessor, d’une taille de 500 MB
  • Sur un système Ryzen 9 9950X, cela prend environ 5 secondes avec des fichiers en cache, d’où l’idée de chercher à améliorer cela

Étape 1 : reconstruire le paquet

  • Téléchargement du code source de jq depuis Launchpad, puis reconstruction sans aucun drapeau
  • Résultat : 2 à 4 % d’amélioration des performances
  • Résultats du benchmark
    • jq compilé : moyenne de 4,517 secondes
    • paquet Ubuntu par défaut : moyenne de 4,641 secondes
    • amélioration des performances : 1,03× plus rapide

Étape 2 : utiliser Clang et des drapeaux d’optimisation avancés

  • Compilation avec Clang-18, utilisation d’un niveau d’optimisation plus élevé et de la LTO
  • Principaux drapeaux utilisés :
    • -O3 → niveau d’optimisation renforcé
    • -flto → application de la Link-Time Optimization
    • -DNDEBUG → exclusion du code de débogage
  • Résultats du benchmark
    • jq compilé : moyenne de 3,853 secondes
    • paquet Ubuntu par défaut : moyenne de 4,631 secondes
    • amélioration des performances : 1,20× plus rapide

Étape 3 : ajout de TCMalloc

  • Utilisation de TCMalloc à la place du malloc par défaut de GNU libc
  • Compilation après ajout de -L/usr/lib/x86_64-linux-gnu -ltcmalloc_minimal
  • Résultats du benchmark
    • jq compilé : moyenne de 3,253 secondes
    • paquet Ubuntu par défaut : moyenne de 4,611 secondes
    • amélioration des performances : 1,42× plus rapide

Étape 4 : appliquer le préchargement dynamique de TCMalloc

  • Utilisation de TCMalloc via préchargement dynamique sur le paquet Ubuntu par défaut
  • Résultats du benchmark
    • jq par défaut : moyenne de 4,601 secondes
    • jq avec TCMalloc : moyenne de 4,082 secondes
    • amélioration des performances : 1,13× plus rapide

Étape 5 : tester le préchargement dynamique d’autres allocateurs

  • Test de jemalloc et mimalloc, deux autres allocateurs mémoire fournis par Ubuntu
  • mimalloc offre les meilleures performances
  • Résultats du benchmark
    • jq par défaut : moyenne de 4,123 secondes
    • jq avec TCMalloc : moyenne de 4,130 secondes
    • jq avec jemalloc : moyenne de 3,510 secondes
    • jq avec mimalloc : moyenne de 3,154 secondes → performances améliorées de 1,31×

Étape 6 : compiler directement avec mimalloc

  • Liaison statique de mimalloc au lieu d’un préchargement dynamique
  • Performances maximisées
  • Résultats du benchmark
    • jq compilé : moyenne de 2,428 secondes
    • paquet Ubuntu par défaut : moyenne de 4,606 secondes
    • amélioration des performances : 1,90× plus rapide

🚀 Résultat final

  • Le jq compilé manuellement est 90 % plus rapide que le paquet Ubuntu
  • Performances sur le traitement de 13 000 fichiers JSON pour un total de 2,2 GB :
    • jq compilé : 0,755 seconde
    • jq par défaut : 1,424 seconde
    • amélioration des performances : environ 2×

1 commentaires

 
GN⁺ 2025-03-19
Commentaire Hacker News
  • Le titre « Reconstruire des paquets Ubuntu et changer l’allocateur mémoire pour les rendre 90 % plus rapides » ressemble à du clickbait

    • Il ne s’agit que d’un seul paquet, et une partie des gains de performance n’a pas été obtenue par recompilation
    • Quelqu’un a déjà remplacé l’implémentation de malloc en préchargeant jemalloc, avec des résultats positifs pour stabiliser l’utilisation mémoire
    • Cela a résolu un problème de fuite mémoire, et il est plus probable qu’il s’agissait en réalité d’un problème de fragmentation mémoire plutôt que d’un défaut propre à l’application
  • L’ingénierie est l’art du compromis

    • L’article explique que l’essentiel du gain de performance provient de la spécialisation de l’allocateur mémoire
    • Dans les projets multithread, le choix de l’allocateur est important, et ce qui accélère un projet peut provoquer des plantages dans un autre
    • Il faut aussi prendre en compte la stratégie de réallocation, et choisir entre stabilité à long terme et vitesse à court terme
    • Lors du développement d’un éditeur vidéo, différents allocateurs ont été testés, et l’allocateur de glibc s’est révélé offrir une stabilité durable
  • Gentoo Linux est un système d’exploitation conçu pour être optimisé selon les usages spécifiques de l’utilisateur

    • Une fois la configuration initiale effectuée, son utilisation est simple, et cela rappelle à quelqu’un le souvenir de nombreuses amitiés nouées sur le canal Gentoo Linux
    • Les premières versions de ChromeOS reposaient essentiellement sur une installation personnalisée de Gentoo Linux
  • Installer manuellement des paquets comme jq peut les exclure des mises à jour de sécurité

    • Par exemple, onigurama a déjà fait l’objet d’une mise à jour de sécurité, et si une situation similaire se reproduit, cela peut devenir une vulnérabilité
    • Plusieurs failles de sécurité, dont CVE-2017-9224, ont déjà été corrigées
  • Utiliser un malloc non officiel peut entraîner des bugs étranges

    • Dès qu’on dépasse les drapeaux utilisés par les développeurs, la probabilité de problèmes augmente fortement
  • En lisant qu’un simple changement peut apporter un énorme gain de vitesse, quelqu’un veut en informer le développeur de jq

    • L’article semble ne pas avoir envisagé cette option, et elle n’est pas mentionnée non plus dans les commentaires
  • Compiler des paquets depuis les sources ou télécharger les binaires officiels peut être bénéfique

    • Il était difficile de vérifier les mises à jour des installations manuelles et des paquets compilés depuis les sources, mais un outil a été développé pour résoudre ce problème
  • La fonction cargo install de Rust est utile, car elle permet des optimisations adaptées à une plateforme donnée

    • jaq et yq sont souvent utilisés comme options offrant de meilleures performances lors de l’utilisation de jq
  • Après avoir changé d’allocateur mémoire, il serait possible de reconstruire des paquets Ubuntu pour les rendre 90 % plus rapides

    • Cela pourrait aussi fonctionner sur Debian et RedHat
    • Au départ, quelqu’un a cru qu’il s’agissait d’un article expliquant comment transformer Ubuntu en Linux From Scratch