13 points par GN⁺ 2026-01-15 | 9 commentaires | Partager sur WhatsApp
  • La comparaison des performances entre Rust et le C est une question complexe, dont la réponse dépend de la définition de l’hypothèse « toutes choses étant égales par ailleurs »
  • Dans le cas de l’assembleur inline, les deux langages peuvent générer exactement le même code assembleur, donc il n’y a pas de différence de vitesse propre au langage
  • Pour la disposition mémoire des structures, Rust peut obtenir une taille plus petite grâce au réordonnancement des champs, mais l’attribut #[repr(C)] permet aussi d’avoir exactement la même disposition qu’en C
  • En pratique, les vérifications à l’exécution et les habitudes des développeurs peuvent entraîner des différences de structure du code et de performances
  • En conclusion, il n’existe pas de différence de performances due aux limites intrinsèques du langage ; le résultat varie selon le projet et les développeurs

Le problème posé et l’ambiguïté des hypothèses

  • Le point de départ est une question soulevée sur Reddit : « À conditions égales, Rust peut-il être plus rapide que le C ? »
  • L’expression « toutes les conditions sont identiques » est elle-même très difficile à définir lorsqu’on compare des langages
  • Une comparaison de performances dépend non seulement des différences entre langages, mais aussi de la forme du code, des choix de développement et des optimisations du compilateur

Comparaison de l’assembleur inline

  • Rust prend en charge l’assembleur inline au niveau du langage, tandis que le C l’implémente via des extensions de compilateur
    • Dans les deux langages, on peut écrire le même exemple utilisant l’instruction rdtsc
    • L’assembleur généré par rustc 1.87.0 et clang 20.1.0 est exactement identique
  • Ce cas ne montre pas une différence de performances entre langages, mais il prouve que Rust permet le même niveau de contrôle bas niveau que le C
Publicité

Différences de layout des structures

  • Les structures Rust peuvent optimiser l’usage mémoire via le réordonnancement des champs
    • Dans l’exemple, la structure Rust occupe 16 octets, contre 24 octets pour la structure C équivalente
  • En C, il faut modifier manuellement l’ordre des champs pour obtenir la même taille
  • En Rust, l’attribut #[repr(C)] permet d’imposer exactement la même disposition mémoire qu’en C

Facteurs sociaux et humains

  • Grâce aux vérifications de sûreté de Rust, il existe des cas où les développeurs peuvent tenter des optimisations plus agressives
    • Dans le projet Stylo de Mozilla, deux tentatives de parallélisation en C++ ont échoué, alors que l’implémentation en Rust a réussi
    Publicité
  • Même sur un projet identique, les performances et la stabilité du code produit peuvent varier selon le langage et le niveau de maîtrise des développeurs
  • Entre débutants et experts, et selon la familiarité avec le langage, le résultat d’une « même tâche » peut différer, ce qui rend toute comparaison simpliste difficile

Vérifications à la compilation et à l’exécution

  • Une grande partie des vérifications de sûreté de Rust est effectuée à la compilation, mais certaines restent faites à l’exécution
    • Par exemple, lors d’un accès array[0], Rust effectue une vérification des bornes, alors que le C ne le fait pas
    • En Rust, l’utilisation de get_unchecked() permet d’obtenir le même comportement qu’en C
  • Lorsque le compilateur peut prouver la sûreté, les deux langages peuvent éliminer ces vérifications via l’optimisation
  • Ces différences influencent la manière d’écrire le code et peuvent, au final, provoquer des écarts de performances

Conclusion

  • Même en supposant que le C soit « le langage le plus rapide », rien n’empêche Rust d’atteindre le même niveau de performances
  • Plus que les limites du langage lui-même, ce sont les caractéristiques du projet, les compétences des développeurs et les contraintes de temps qui déterminent les écarts de performances
  • Ainsi, la question « Rust est-il plus rapide que le C ? » relève davantage du contexte d’ingénierie que d’une simple comparaison entre langages

9 commentaires

 
jokerized 2026-01-16

Dans l’embarqué, on code en tenant compte jusqu’à la taille des lignes de cache du matériel. La question, c’est jusqu’où un programmeur peut pousser l’optimisation extrême au niveau du langage, ainsi que les performances de la bibliothèque standard et du compilateur. De toute façon, comme les deux prennent en charge le bas niveau, la légère différence d’overhead sera probablement négligeable. Donc je ne pense pas que ce soit un débat très pertinent… Si une optimisation extrême est nécessaire, une intervention humaine finit de toute façon par s’imposer. Les compilateurs ne sont pas aussi parfaits qu’on pourrait le croire.

 
iolothebard 2026-01-15

Je pense que Rust sera plutôt un remplaçant de C++ que de C. Le C est pratiquement le seul langage (peut-être même le dernier) dans lequel on peut deviner le code que le compilateur va produire…

 
secret3056 2026-01-16

Zig n’est pas mauvais non plus... TT

 
iolothebard 2026-01-15

À force d’écrire, c’est devenu un résumé façon IA, snif snif

 
galadbran 2026-01-16

Vous ne l’avez pas fait exprès, n’est-ce pas ? Hé hé.

 
winmain 2026-01-15

Cela dépend des capacités du compilateur.

Il suffit d’assembler le même code pour le voir.

 
jjw9512151 2026-01-15

On dirait que les gars de ffmpeg pensent que Rust n’est pas plus rapide que C, haha : https://www.memorysafety.org/blog/rav1d-perf-bounty/

 
GN⁺ 2026-01-15
Avis sur Hacker News
  • En résumé, la vitesse maximale est presque la même, mais dans le code réel l’écart peut être important
    En particulier, le multithreading est un facteur majeur. En Rust, toutes les variables globales doivent être thread-safe, qu’on utilise des threads ou non, et le borrow checker limite l’accès mémoire soit au partage, soit à la modification
    Du coup, écrire du code multithread en Rust est presque la norme. À l’inverse, en C, créer des threads reste contraignant à cause des problèmes de compatibilité entre plateformes et des risques au débogage

    • Honnêtement, je pense que cette différence vient surtout de la commodité de la bibliothèque standard
      Construire avec des threads n’est pas difficile en C, mais c’est plus lourd que std::thread::spawn(move || { ... }); en Rust
      Plus que la sûreté mémoire, c’est le modèle de concurrence du langage qui a le plus d’impact. Go permet aussi de paralléliser facilement avec go f(), même sans être memory-safe
      Personnellement, j’ai vu plus souvent des heisenbugs en Go
    • Au-delà du multithreading, je me demande si le système de types de Rust fournit plus d’informations qui ouvrent davantage de possibilités d’optimisation
    • En réalité, une seule ligne comme #pragma omp for suffit aussi pour paralléliser simplement en C
    • Je ne comprends toujours pas pourquoi il faut lier TBB pour faire du multithreading sous Linux. À mon avis, ça devrait être inclus par défaut
    • Si on ajoute des threads à tout-va, il faut aussi se demander ce qu’il en est de la consommation d’énergie et des conditions de course
  • Grâce aux traits de Rust, on peut construire des abstractions plus rapides et plus souples
    En C, on peut imiter ça avec des macros ou des pointeurs de fonction, mais en Rust l’appelant peut choisir entre dispatch dynamique et dispatch statique
    En embarqué, les pointeurs de fonction perturbent le cache et pénalisent les performances, alors que les traits Rust permettent l’inlining et sont donc bien plus efficaces

    • J’aime bien aussi le bidouillage ELF, mais pour les performances il faut bien connaître le linker, l’ABI et le format binaire
      Que ce soit en Rust ou en C, on finit de toute façon par manipuler les choses au niveau de l’octet, et aujourd’hui les outils de binary patching se sont améliorés, donc c’est plus facile à exploiter
    • Bien sûr, en Rust aussi, si on met Box<dyn Trait> dans une signature de fonction, l’appelant se retrouve forcé d’utiliser le dispatch dynamique
      Avec impl Trait, le choix reste du côté de l’appelant
    • En revanche, quand on utilise beaucoup de traits, la hausse du temps de compilation devient visible. Plus les traits sont complexes, plus la compilation ralentit
    • L’approche à la C consiste justement à éviter toute abstraction
  • Personnellement, je considère que Rust, C et C++ appartiennent pratiquement à la même famille de langages bas niveau, donc les écarts de performances sont minimes
    Les règles strictes d’aliasing de Rust favorisent l’optimisation, et l’UB (comportement indéfini) en C/C++ existe aussi dans une logique de performance
    Les génériques de Rust et de C++ sont aussi bien plus puissants que ce qu’offre C, par exemple un tri fondé sur des templates est plus facile à optimiser en inline que qsort()

    • Les templates C++ restent encore plus expressifs que Rust, mais l’écart se réduit peu à peu
    • En fait, c’est davantage une question de conception de la bibliothèque standard que de langage. Même en C, on peut écrire soi-même une fonction de tri inlineable
    • La gestion du dépassement d’entier en Rust suit le comportement par défaut de la plateforme, donc le résultat peut varier selon les optimisations
    • Un langage n’est qu’un moyen de décrire un comportement ; la vitesse réelle dépend du compilateur et de l’environnement d’exécution
    • Au final, l’écart de performances entre ces trois langages relève surtout du rendement par rapport à l’effort. Le C est rapide, mais coûte cher en développement, et Rust se situe quelque part entre les deux
  • Je pense que ce genre de débat sur la vitesse entre langages n’a, la plupart du temps, pas grand sens
    Plus que le langage lui-même, c’est l’implémentation du compilateur qui détermine les performances

    • Cela dit, la conception du langage a un effet majeur sur les possibilités d’optimisation. Le « compilateur suffisamment intelligent » reste encore largement un mythe
  • Rust, C et C++ sont tous des langages bas niveau, mais tout dépend de ce qu’on entend par « rapide »
    Parle-t-on de la vitesse maximale d’un code optimisé par des experts, ou de la probabilité qu’un développeur moyen écrive du code rapide dans les limites du budget ?

    • Dans la pratique, c’est surtout la capacité d’optimisation du compilateur qui compte. Les sémantiques mémoire de Rust sont plus riches, donc le compilateur peut en tirer davantage d’informations pour optimiser
      Mais avec une optimisation manuelle poussée, les différences entre langages disparaissent presque
      Cela dit, Rust garde un léger avantage dans le fait qu’il est plus facile d’y écrire du code rapide
    • La plupart des gens utilisent justement cette définition : « un langage dans lequel un développeur moyen peut écrire du code rapide »
    • Les concepteurs de langages réfléchissent à « à quelle vitesse tourne le code typique écrit dans ce langage », donc la question me paraît légitime
  • Je pensais que les points forts de Rust étaient le multithreading et l’allocation sur la pile
    Grâce au modèle de propriété, on peut mettre davantage de choses sur la pile qu’en C/C++, ce qui réduit le surcoût de malloc/free

    • Oui, mais ici la discussion portait moins sur ce genre de différences concrètes que sur une comparaison conceptuelle du point de vue de la conception des langages
      Comme ce sujet déclenche souvent des débats émotionnels, je voulais parler davantage de différences de manière de penser que de chiffres précis
  • Quand on parle de la « vitesse » d’un langage, il faut regarder deux choses

    1. Quel coût le langage injecte-t-il dans le programme ?
    2. Quelles optimisations le langage rend-il possibles ?
      Rust et C ont très peu de vérifications à l’exécution, donc ils sont plus rapides que Python ou JS
      En revanche, Rust transmet mieux les informations d’aliasing, ce qui laisse davantage de marge à l’optimisation
      En mode debug, il peut être aussi lent que Ruby, mais en mode release il atteint des performances comparables à C
    • J’aime bien ce point de vue. Ça rejoint aussi l’idée des zero-cost abstractions en C++
    • JS est lui aussi très optimisé, mais reste malgré tout un peu plus lent que Rust/C
    • Une autre question est : « quelle vitesse obtient-on avec un développeur ordinaire ? » Il est important de savoir si le langage pousse naturellement à écrire du code rapide
  • Par rapport à C, C++ ou Rust ont des fonctionnalités de compilation plus riches, ce qui facilite l’écriture de code rapide
    Par exemple, ce code est pratiquement impossible à faire en C

  • L’assembleur ne fait pas partie de la norme C, donc il est difficile de le comparer directement à Rust, et Rust est en réalité plus proche du projet GCC par sa nature

  • Dire qu’un langage est « rapide » dépend au fond de l’implémentation et du contexte
    Plus que la vitesse intrinsèque du langage, c’est la combinaison compilateur + matériel qui a le plus d’influence

 
aer0700 2026-01-16

En moyenne, je ne sais pas quelle langue est la plus rapide, mais j’ai l’impression que c’est le C++ qui présente la plus grande dispersion.