1 points par GN⁺ 2025-03-19 | 1 commentaires | Partager sur WhatsApp
  • En reconstruisant la même source de jq et en changeant d’allocateur, le temps de traitement d’un GeoJSON de 500 Mo est passé de 4,606 secondes à 2,428 secondes, soit 1,90 fois plus rapide que le binaire Ubuntu
  • Le benchmark a été réalisé sur un Ryzen 9 9950X avec la parcel map de l’Alameda County Assessor, en extrayant SitusCity pour la condition TotalNetValue < 193000
  • Une simple reconstruction a déjà apporté 2 à 4 % d’amélioration, et la combinaison clang-18, -O3, -flto, -DNDEBUG a atteint 1,20 fois les performances du paquet Ubuntu
  • Le profilage a montré un coût important de l’allocation mémoire ; TCMalloc, jemalloc et mimalloc ont été comparés, et dans les essais avec LD_PRELOAD, mimalloc s’est montré le plus rapide
  • La version finale liée avec mimalloc a aussi enregistré 0,755 seconde contre 1,424 seconde dans un autre cas de traitement d’un JSON de 2,2 Go, montrant que l’écart avec les builds par défaut des distributions peut être important selon la charge de travail

Charge de travail de référence et méthode de mesure

  • L’outil de traitement JSON testé est jq, avec en entrée un fichier GeoJSON de 500 Mo contenant la parcel map de l’Alameda County Assessor
  • La requête exécutée affiche le SitusCity des éléments de la liste de parcelles satisfaisant la condition TotalNetValue < 193000
    • .features[] | select(.properties.TotalNetValue < 193000) | .properties.SitusCity
  • Le /usr/bin/jq par défaut d’Ubuntu prend environ 5 secondes lorsque le fichier est en cache, et les benchmarks détaillés ont été répétés avec hyperfine
  • Pour réduire les variations à l’exécution, le processus a été épinglé au CPU logique 2 avec taskset -c 2
    • Ce réglage vise à éviter l’impact des interruptions système sur le CPU 0 et de la migration entre CPU

Simple reconstruction de la même source

  • Le code source de jq utilisé par Ubuntu a été récupéré, puis configuré et compilé sans options particulières
  • Cette simple reconstruction suffit à rendre le binaire environ 2 à 4 % plus rapide que le paquet binaire Ubuntu
    • Binaire reconstruit : moyenne de 4,517 secondes
    • /usr/bin/jq d’Ubuntu : moyenne de 4,641 secondes
    • Soit environ 1,03 fois les performances

Application de clang et de flags d’optimisation

  • À l’étape suivante, clang-18, un niveau d’optimisation plus élevé, LTO, ainsi que des flags liés au débogage et au profilage ont été appliqués ensemble
  • Les flags clés ayant influé sur les performances sont -O3, -flto et -DNDEBUG
    • -O3 utilise un niveau d’optimisation supérieur à -O2
    • -flto active l’optimisation au moment de l’édition de liens
    • -DNDEBUG réduit le coût des assertions, qui ressortait fortement dans le profilage
  • Voici un exemple de configuration appliquée
    • CC=clang-18
    • LDFLAGS="-flto -g -Wl,--emit-relocs -Wl,-z,now -Wl,--gc-sections -fuse-ld=lld"
    • CFLAGS="-flto -DNDEBUG -fno-omit-frame-pointer -gmlt -march=native -O3 -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections"
  • Ce build était 1,20 fois plus rapide que le binaire Ubuntu
    • Reconstruction optimisée : moyenne de 3,853 secondes
    • /usr/bin/jq d’Ubuntu : moyenne de 4,631 secondes

Expériences de remplacement de l’allocateur

  • jq est un programme C complexe, et le profilage a montré que l’allocation mémoire constituait le coût principal
  • Une première reconstruction a été faite en liant TCMalloc, fourni sous forme de paquet Ubuntu
    • -L/usr/lib/x86_64-linux-gnu -ltcmalloc_minimal a été ajouté à LDFLAGS
    • Binaire reconstruit : moyenne de 3,253 secondes
    • /usr/bin/jq d’Ubuntu : moyenne de 4,611 secondes
    • Résultat : 1,42 fois plus rapide que le binaire Ubuntu
  • Remplacer uniquement l’allocateur via LD_PRELOAD avec le binaire Ubuntu par défaut permet aussi une certaine amélioration
    • Par défaut : moyenne de 4,601 secondes
    • TCMalloc préchargé : moyenne de 4,082 secondes
    • Soit 1,13 fois plus rapide que la valeur par défaut

Préchargement dynamique et configuration THP

  • jemalloc, mimalloc et TCMalloc, fournis par Ubuntu, ont été comparés avec LD_PRELOAD
  • Cette comparaison a été obtenue après définition des variables d’environnement suivantes
    • MIMALLOC_LARGE_OS_PAGES=1
    • MALLOC_CONF="thp:always,metadata_thp:always"
    • GLIBC_TUNABLES=glibc.malloc.hugetlb=1
  • Au final, mimalloc est le plus rapide
    • glibc par défaut : moyenne de 4,123 secondes
    • TCMalloc préchargé : moyenne de 4,130 secondes
    • jemalloc préchargé : moyenne de 3,510 secondes
    • mimalloc préchargé : moyenne de 3,154 secondes
  • L’activation de THP profite à la fois à l’allocateur glibc, à jemalloc et à mimalloc
  • THP + mimalloc est 31 % plus rapide que THP + glibc, et 48 % plus rapide que la configuration par défaut de glibc

Résultat final du build lié avec mimalloc

  • Le préchargement dynamique n’étant pas jugé idéal sur le plan des performances, la dernière étape a consisté à reconstruire jq en le liant à mimalloc
  • Le build final était 1,90 fois plus rapide que le paquet binaire Ubuntu
    • Reconstruction avec mimalloc : moyenne de 2,428 secondes
    • /usr/bin/jq d’Ubuntu : moyenne de 4,606 secondes
    • Chaque benchmark repose sur 10 exécutions
  • Le même build a aussi été utilisé avec une autre application
    • Traitement de 2,2 Go de JSON répartis dans 13 000 fichiers
    • rush a été utilisé pour la parallélisation
    • jq reconstruit avec mimalloc : 0,755 seconde
    • jq du paquet Ubuntu : 1,424 seconde
  • Dans ce cas distinct également, le gain de vitesse approche presque 2 fois

1 commentaires

 
GN⁺ 2025-03-19
Avis sur Hacker News
  • Les titres putaclic du genre « reconstruire un paquet Ubuntu et le rendre 90 % plus rapide en changeant l’allocateur mémoire » donnent envie de donner un coup à travers TCP/IP. Ce n’était qu’un seul paquet, et certaines améliorations ne venaient même pas de la recompilation.
    Cela dit, il m’est déjà arrivé d’injecter jemalloc dans un programme avec LD_PRELOAD pour remplacer l’implémentation de malloc, et le résultat a été plutôt bon. Je n’ai pas mesuré les performances, mais l’utilisation mémoire de l’application s’est stabilisée et un problème qui ressemblait à une fuite mémoire a disparu. En réalité, il est très probable que ce n’était pas un problème de l’application elle-même, mais de la fragmentation mémoire du malloc standard.

    • J’ai étudié l’allocateur mémoire de glibc, et ce n’était pas de la fragmentation mémoire, mais dû aux caches par thread qui ne sont jamais rendus au noyau. Même quand free() est appelé, sauf situation exceptionnelle, la mémoire n’est pas réellement libérée de l’extérieur.
      Plus il y a de threads et de cœurs CPU, plus le problème s’aggrave. Une solution simple consiste à définir la variable d’environnement « magique » MALLOC_ARENA_MAX=2 pour limiter le nombre de caches. Une autre méthode consiste à faire appeler régulièrement malloc_trim() par l’application pour vider les caches, mais cela nécessite de modifier le code source.
      https://www.joyfulbikeshedding.com/blog/2019-03-14-what-caus...
    • Exact, j’ai failli y croire pendant un instant moi aussi. Mais il est aussi facile de faire porter la faute à Ubuntu. Personnellement, je trouve qu’Ubuntu assemble plutôt bien ses paquets, et les compile effectivement avec les options de protection de pile activées.
      À l’inverse, je suis content qu’ils ne compilent pas avec -O3, potentiellement source de bugs. Cela peut être intéressant pour certains éléments où les performances sont critiques, mais je ne voudrais pas que tout le système soit compilé avec -O3.
    • Cela semble clairement exagéré, puisqu’il est impossible d’obtenir une telle amélioration globale avec la seule explication donnée dans l’article. Les 90 % plus rapide sont un chiffre de microbenchmark.
    • Je me demande combien de distributions binaires prépackagées sont construites avec les options les plus sûres pour l’OS et le matériel, au détriment des meilleures performances possibles. Honnêtement, j’imagine que c’est le cas de la plupart.
      Il y a longtemps, j’ai commencé à compiler Mozilla et mon noyau Linux selon mes préférences, et j’obtenais généralement un gain de performances raisonnable. Tout l’objectif d’une distribution comme Gentoo Linux, par exemple, est justement de tirer des gains de performances en compilant tout depuis les sources avec des optimisations.
    • Le titre est putaclic, mais c’est une bonne chose d’encourager les développeurs d’apps à tenter une recompilation. Surtout quand le CPU est le goulot d’étranglement dans quelques utilitaires courants comme jq, grep, ffmpeg ou ocrmypdf, et que ces utilitaires Unix génériques sont souvent construits comme des cibles générales, pas pour une application particulière.
  • L’ingénierie est affaire de compromis. Dans l’article, l’essentiel des gains vient de la spécialisation de l’allocateur mémoire. Il faut garder à l’esprit que certains projets sont multithreadés, qu’ils allouent dans un thread, écrivent les données dans un autre et les libèrent parfois dans un troisième
    L’allocateur doit gérer cela, donc une accélération dans un projet peut se transformer en crash dans un autre. La stratégie de réallocation pose aussi problème. Certains programmes préallouent et ne touchent plus jamais à malloc, tandis que d’autres libèrent et réallouent en permanence. La qualité de la gestion de la fragmentation compte, tout comme le fait que le temps de fonctionnement soit de 10 secondes ou de 10 ans. Parfois, le choix de l’allocateur fait la différence entre stabilité à long terme et vitesse à court terme
    J’ai expérimenté plusieurs allocateurs en créant un éditeur vidéo qui met en cache des images pendant des tests en 4K. À 32 Mo par image et 60 i/s, cela fait presque 2 Go par seconde pour une seule piste. On atteint très vite les limites de l’allocateur, et on se rend compte qu’au moins l’allocateur glibc par défaut est le meilleur pour la stabilité à long terme. Mais dans les benchmarks courts, c’est le plus lent

    • Mimalloc est un allocateur généraliste, comme JEMalloc / TCMalloc. glibc est réputé être un allocateur assez mauvais, et MIMalloc ou le TCMalloc récent — c’est-à-dire pas la version fournie par défaut avec Ubuntu — sont très en avance sur glibc
      Bien sûr, l’ampleur des gains peut varier, mais les benchmarks montrent généralement une amélioration globale. Que cela ait du sens pour une application donnée est une tout autre question. Quant aux crashs, ce sont tous des allocateurs généralistes multithreadés, ils ne se comportent donc pas différemment de glibc à cet égard, et les bugs pourraient tout aussi bien exister dans glibc
    • Je manipule moi aussi de grosses images vidéo 8K [1]. Si l’on parle des images elles-mêmes, 60 allocations par seconde, ce n’est rien. glibc est lent pour une seule raison : chaque allocation dépasse DEFAULT_MMAP_THRESHOLD_MAX, qui vaut 32 MiB sur les plateformes 64 bits, si bien qu’il est impossible de convaincre glibc de les mettre en cache, comme le documente le manuel de mallopt
      À chaque fois, il demande directement de la mémoire au noyau avec mmap et la rend avec munmap. Ces appels système sont un peu lents et, dans mon cas, le coût des défauts de page sur chaque page mémoire au premier accès est trop élevé pour atteindre les objectifs de performance. La solution est vraiment simple : pour les images vidéo uniquement, utiliser une liste libre maison au-dessus d’un allocateur généraliste ou de mmap. Comme les allocations de taille exactement identique se répètent de manière très stable, cela fonctionne bien
      [1] Un peu moins de 64 MiB au format UYVY, et un peu moins de 48 MiB au format I420
    • J’ai un peu de mal à comprendre ce commentaire. Je ne connais pas très bien C ni les compilateurs C, mais j’ai lu tout le gist, j’y ai appris beaucoup de choses et je l’ai trouvé utile
      Mais en lisant ce commentaire parent, je me demande si je n’ai pas complètement mal compris l’article. Le ton donne l’impression que ce que propose le gist est quelque chose qu’il ne faut absolument jamais faire, une suggestion horrible qui passe à côté de toute cette complexité. Est-ce que quelqu’un peut m’aider à comprendre si le gist d’origine est un bon texte, s’il soulève des points valables, ou s’il n’a aucune valeur ? Jusqu’à lire ce commentaire, je le trouvais utile, mais je me rends compte que je ne suis peut-être pas assez compétent pour faire la différence
    • C’est pour ça qu’utiliser un seul allocateur pour tout, partout, est une mauvaise idée. Que les applications monothreadées, et même les applications multithreadées qui gèrent strictement leurs ressources, paient toutes le coût de la sécurité thread, c’est terrible
    • C’est une souffrance courante. Si vous utilisez le langage adapté au projet, les gens vous diront que vous auriez dû en utiliser un autre pour telle ou telle raison
      Si vous utilisez l’algorithme de compression adapté aux données, les gens vous expliqueront pourquoi vous êtes stupide et auriez dû en choisir un autre. Récemment, j’ai dû compresser une longue chaîne JSON particulière pour la mettre dans Dynamo, et après avoir testé minutieusement tous les algorithmes populaires, Brotli était largement devant. Cela n’a pas empêché presque toutes les personnes de passage de me dire que zlib était meilleur. C’est parfois assez épuisant
  • Gentoo Linux est, dans les faits, une distribution conçue pour ce genre de personnes, afin de pouvoir optimiser leur machine Linux pour leurs propres usages
    Après la configuration initiale, elle est assez simple et facile à utiliser. Je me souviens m’être fait pas mal d’amis sur le canal Gentoo Linux de Matrix, c’était une époque sympa
    https://www.gentoo.org/
    Fait amusant, les premières versions de ChromeOS étaient essentiellement une installation Gentoo Linux personnalisée. Je ne sais pas si ChromeOS utilise encore Gentoo Linux en interne aujourd’hui

    • C’est vrai, mais il vaut la peine de préciser qu’ici, optimisation ne veut pas forcément dire performance
      J’utilise Gentoo depuis 20 ans, mais je ne l’ai jamais utilisé pour les performances. Gentoo est excellent quand on sait comment on veut que le système se comporte, et il aide à y parvenir
    • Je découvre le mème « install gentoo » façon HN. C’est clairement plus raffiné
      L’objectif de Gentoo est d’avoir un système d’exploitation qui compile tous les programmes depuis les sources plutôt que d’utiliser des paquets binaires précompilés. Cela permet des optimisations avancées et une personnalisation poussée, mais cela signifie aussi que même les composants les plus fondamentaux, comme le noyau, doivent être compilés depuis les sources. Dans la communauté Linux, Gentoo est réputé être un système d’exploitation très complexe à cause de son processus d’installation exigeant. Une installation Gentoo de base démarre directement sur une invite de commande, et l’utilisateur doit partitionner les disques lui-même, télécharger puis décompresser un paquet appelé « Stage 3 tarball », installer les paquets manuellement et construire le système. Les nouveaux utilisateurs, ou ceux qui manquent d’expérience, ne savent souvent pas quoi faire lorsqu’ils arrivent dans l’installateur et qu’il n’y a pas d’interface graphique. Les membres de /g/ exagèrent souvent la valeur de Gentoo pour pousser de nouveaux utilisateurs à tenter l’installation
    • J’ai utilisé Gentoo en continu depuis 2003, puis j’ai migré très récemment, fin 2024, après avoir essayé Void Linux. Sur Void, permettre à l’utilisateur final de compiler depuis les sources n’est pas un objectif déclaré ni une fonctionnalité d’architecture, mais il y a de bonnes chances que l’on puisse effectivement le faire fonctionner
      Il peut y avoir un ou deux accrochages, mais avec une expérience Linux globale suffisante, on a de bonnes chances d’aller dans la recette de build, de la corriger, de la faire fonctionner comme nécessaire, puis de contribuer les modifications en amont. C’est le résultat d’une focalisation obsessionnelle sur le minimalisme et du refus de toute forme de suringénierie. C’est aussi ce qui m’a manqué pendant toutes mes années sous Gentoo. Avec Gentoo, je finissais toujours par bricoler des USE flags et des masques de paquets d’une manière qui n’aidait pas vraiment les autres utilisateurs. Le système de build était tellement complexe qu’au fil des années, il était trop difficile de vraiment le maîtriser, de corriger les problèmes à la racine et de contribuer en amont. Void peut aussi être une base idéale quand on ne veut pas compiler tout le système depuis les sources, mais qu’on veut mélanger les binaires fournis par la distribution avec des paquets compilés soi-même depuis les sources
    • J’ai utilisé Gentoo pendant un moment, mais la tentation de tout modifier sans fin finissait par casser mon système. Ce n’était pas la faute de Gentoo, c’était la mienne
      Je suis ensuite passé à ArchLinux, et dans l’ensemble ça m’a convenu. Si on utilise un processeur assez standard, je ne pense pas que Gentoo apporte un si grand avantage
    • D’après ce que je sais, ChromeOS basé sur Gentoo est en train d’être remplacé par Android
  • En faisant cela, on sort non seulement des mises à jour de sécurité de jq, mais aussi de celles d’onigurama, sa dépendance pour l’analyse des expressions régulières. Il y a déjà eu par le passé une mise à jour de sécurité d’onigurama, et si cela se reproduit, on pourrait devenir vulnérable. jq est souvent utilisé pour analyser du JSON non fiable
    Il s’agissait d’une « mise à jour de sécurité : correction de plusieurs déréférencements de pointeurs invalides, corruptions mémoire par écriture hors limites et dépassements de tampon sur la pile », concernant les CVE-2017-9224, CVE-2017-9226, CVE-2017-9227, CVE-2017-9228 et CVE-2017-9229

    • Avec un gestionnaire de paquets en espace utilisateur comme Gentoo Prefix, on peut installer ce build personnalisé tout en continuant à recevoir les mises à jour de sécurité
    • Il y a quand même là comme une graine d’idée pour un système de gestion de paquets qui déciderait intelligemment, selon la plateforme, s’il faut compiler ou non, non ? Le gain de performance semble assez important pour ne pas le laisser de côté
    • En général c’est vrai, mais dans ce cas c’est faux. Le build décrit dans le gist fait toujours un lien dynamique vers onigurama. onigurama se trouve dans un autre paquet, libonig5, et sera mis à jour normalement
    • Je me demande à quel point ce genre de CVE est applicable en pratique. C’est un peu comme dire qu’en utilisant une porte intérieure chez soi, on se prive de la sécurité offerte par une porte de coffre-fort. Ce n’est pas faux, mais il y a une raison pour laquelle toutes les portes d’une banque ne sont pas des portes de coffre
      Je ne cherche pas à minimiser la valeur du système des CVE, mais il est difficile de nier que l’impact réel varie énormément d’une découverte à l’autre
    • Tout à fait. Et en remplaçant l’allocateur et en changeant les options du compilateur, on peut aussi devenir par hasard immunisé contre des attaques qui dépendent d’une certaine disposition mémoire
  • Ça fait un moment que je n’ai pas touché à ce genre de choses, mais dans mon souvenir, dès qu’on dépasse les options utilisées par les développeurs amont, on s’expose à des bugs étranges et à une indifférence abyssale quand ces bugs apparaissent. Ici, je parle bien des développeurs amont, pas des mainteneurs de paquets des distributions
    Je n’ai jamais utilisé de malloc autre que celui de la libc, mais j’imagine que le même principe s’applique

    • Deux choses opposées peuvent être vraies en même temps. Si un individu cherche à ne pas être différent le moins du monde, il suit le même chemin que le plus grand nombre et a, à court terme, les meilleures chances de réussite
      Mais si tout le monde fait cela, on obtient une monoculture, et une monoculture est fragile et mauvaise. Le code ne devient un peu plus robuste que parce qu’il est compilé dans d’autres contextes : autres plateformes, compilateurs, options, bibliothèques, etc. Un bug que la plupart des gens n’ont pas déclenché parce que leur plateforme ou leurs options de build passent par hasard juste à côté du piège reste un bug, et il est préférable pour le code de le trouver et de le corriger. En tant qu’individus, nous gagnons tous à ce que le code devienne globalement plus robuste plutôt que fragile
    • Je compile moi-même mon emacs depuis longtemps, et je n’ai encore jamais rencontré de bug étrange. Je pensais qu’il suffisait d’éviter les optimisations non sûres
      Bien sûr, je pensais aussi que -march=native était la principale amélioration que j’observais, mais cet article montre que ce n’est pas forcément le cas. Les applications qui utilisent des nombres à virgule flottante ont peut-être aussi davantage d’aspérités
    • À l’inverse, si une optimisation apporte des gains de façon cohérente sur plusieurs plateformes, on peut convaincre les développeurs amont de l’implémenter eux-mêmes. Il n’est pas nécessaire que ce soit toutes les plateformes : si le gain de performance est suffisamment important sur une seule architecture, cela peut justifier d’ajuster la configuration pour ce build
  • Cela revient plutôt à l’avoir recompilé avec un autre allocateur qui donne de bons résultats dans les benchmarks pour un workflow précis

    • À peu près n’importe quoi peut faire mieux que le malloc de glibc. Le fait que les distributions continuent d’utiliser le malloc de glibc au lieu de mimalloc ou jemalloc relève quasiment du manquement professionnel
    • Sait-on seulement pour quel type de charge de travail le malloc de glibc est bon ?
  • Je me demande comment les performances se comparent à celles de ce clone de jq basé sur Rust
    cargo install --locked jaq
    Pour activer des optimisations adaptées à une famille de CPU donnée, on peut aussi ajouter RUSTFLAGS="-C target-cpu=native". cargo install est une fonctionnalité sous-estimée de Rust, parfaitement adaptée au genre d’usage décrit dans l’article. Comme l’outil est compilé depuis les sources, on peut choisir des fonctionnalités ou instructions propres à la plateforme qui ne sont généralement pas incluses dans les binaires afin de rester compatibles avec de vieux CPU. Pas besoin non plus de cloner le dépôt ni de comprendre comment le build fonctionne : tout vient avec
    jaq[1] et yq[2] sont mes choix quand j’utilise jq et que j’ai besoin d’un gain de performances rapide et facile
    [1] https://github.com/01mf02/jaq
    [2] https://github.com/mikefarah/yq

    • De temps en temps, je compare jaq à jq et gojq, avec ma solution jq pour l’AoC 2022 day 13 comme test
      https://gist.github.com/oguz-ismail/8d0957dfeecc4f816ffee79d...
      Il reste encore derrière les deux
    • Petit bonus que certains ignorent peut-être : quand on veut utiliser directement un dépôt, cargo install dispose aussi d’un flag --git permettant d’indiquer l’URL du dépôt. C’est utile lorsqu’il n’existe pas de paquet public, ou qu’on veut un commit récent qui n’a pas encore été publié
      Je l’ai déjà utilisé plusieurs fois, notamment comme moyen simple d’installer rapidement des outils bricolés pour mon usage perso après les avoir poussés dans un dépôt, sans avoir à mettre en place un processus de release ni à copier des binaires à la main sur mes machines personnelles, tout en gardant la trace exacte du commit utilisé pour le build
  • Si l’on veut vraiment faire cela, il suffit de demander à Ubuntu de récupérer le paquet source exact voulu. Dans ce cas, on peut utiliser apt-get source jq
    Ensuite, on entre dans le paquet et on recompile comme on veut. On peut aussi le repackager pour le distribuer ou l’archiver. On obtient ainsi un résultat bien plus proche de l’Ubuntu amont, au lieu de récolter toute une série d’erreurs bizarres et d’incohérences

  • Le titre prête à confusion. Cela veut dire 90 % du temps gagné, et en réalité c’est environ 45 % plus rapide
    C’est un peu intéressant si l’on s’intéresse à la façon dont on utilise le langage. On pourrait aussi dire qu’on fait 90 % de travail en plus dans le même temps, ce qui correspond à d’autres unités de vitesse courantes, comme les miles par heure, les mots par minute ou les bits par seconde. Mais en performance informatique, la convention consiste à mesurer le temps nécessaire pour une quantité de travail fixe. Sans doute parce que, la plupart du temps, la quantité de travail est fixe et ce qui varie, c’est le temps d’attente. C’est exactement le cas dans cet article de blog, d’où le fait de mettre le temps au numérateur. L’article lui-même est très intéressant et bien écrit, mais ce n’est pas 90 % plus rapide

    • Ce qui prête encore plus à confusion, c’est la nuance selon laquelle on pourrait rendre tous les paquets 90 % plus rapides. Ici, il s’agit d’un paquet précis
    • Ici, il me semble plus logique d’utiliser « 90% faster » comme une unité de débit, pas comme une unité de temps
      Et si l’on utilisait une unité de temps, on n’emploierait pas le mot « faster ». « 45% less time » et « 45% faster » sont des affirmations très différentes, et les deux ont du sens en programmation comme ailleurs
    • Article lié : https://randomascii.wordpress.com/2018/02/04/what-we-talk-ab...
    • En y repensant, je crois voir pourquoi c’est trompeur : on exprime la variation de la plus grande valeur en pourcentage de la plus petite
      Quand on dit qu’on a « réduit quelque chose de N % », on suppose généralement que ces N % portent sur la chose réduite elle-même, pas sur une autre valeur
    • Ça me semble juste. On peut dire que le paquet, c’est-à-dire le code, est 45 % plus rapide, ou dire que le débit de parsing augmente de 90 %. Mais mélanger les deux crée de la confusion
  • En lisant qu’un changement aussi simple pouvait apporter un gros gain de vitesse, ma première réaction a été de penser qu’il fallait en informer les auteurs de jq. Il peut y avoir des pièges à éviter, et après test ils pourraient peut-être rendre l’outil plus rapide pour tout le monde
    Quel que soit le résultat, un simple signalement semble utile. Pourtant, l’article ne semble même pas envisager cette option, et je ne la vois pas non plus dans les commentaires ici. Est-ce que je rate quelque chose ?

    • Je me demande si Clear Linux d’Intel obtient des gains similaires en utilisant des opcodes plus récents du jeu d’instructions
      Je ne sais pas non plus si l’allocateur glibc y est le standard
      https://en.m.wikipedia.org/wiki/Clear_Linux_OS