< plus rapide <= en C++ ? Démystifions les mythes avec des exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Un mythe qui perdure depuis des décennies

\n\n

Si vous avez déjà jeté un œil sur Stack Overflow dans la section C++, vous avez sûrement vu la question : « Is < faster than <= ? ». Cette question a rassemblé des milliers de vues et des dizaines de pages de discussions. Et ce n’est pas surprenant — le sujet de l’optimisation du code passionne les programmeurs de tous niveaux.

\n\n

La logique semble en béton armé : l’opérateur < compare deux nombres et retourne un résultat, tandis que <= fait la même chose, mais vérifie en plus l’égalité. Donc, < devrait être plus rapide, non ? C’est particulièrement important pour les boucles, où l’opération de comparaison est exécutée des millions de fois.

\n\n

Aujourd’hui, nous allons démystifier ce mythe une fois pour toutes. Vous apprendrez :

\n
    \n
  • Comment les opérateurs fonctionnent réellement au niveau du processeur.
  • \n
  • Pourquoi le compilateur est votre meilleur ami (ou votre pire ennemi, si vous ne lui faites pas confiance).
  • \n
  • Quand la micro-optimisation a du sens, et quand elle est une perte de temps.
  • \n
\n\n

Comment fonctionnent les opérateurs < et <= au niveau assembleur ?

\n\n

Pour comprendre s’il y a une différence, il faut regarder « sous le capot » — ce en quoi le compilateur transforme votre code C++. Considérons deux fonctions simples :

\n\n
bool less_than(int a, int b) {\n    return a < b;\n}\n\nbool less_or_equal(int a, int b) {\n    return a <= b;\n}
\n\n

Compilons-les avec g++ (sans optimisations, option -O0). Voici ce que nous voyons dans le listing assembleur (x86-64) :

\n\n
less_than(int, int):\n    cmp    edi, esi      ; comparer a et b\n    setl   al            ; mettre al=1 si a < b (inférieur)\n    ret\n\nless_or_equal(int, int):\n    cmp    edi, esi      ; comparer a et b\n    setle  al            ; mettre al=1 si a <= b (inférieur ou égal)\n    ret
\n\n

Vous voyez ? La seule différence réside dans les instructions setl (set if less) et setle (set if less or equal). Les deux instructions s’exécutent en un cycle d’horloge du processeur. Sur les CPU modernes (Intel Core i7, AMD Ryzen), elles ont une latence identique — 1 cycle.

\n\n

Conclusion n°1 : Au niveau des instructions machine, il n’y a aucune différence de performance entre < et <=. Point final.

\n\n

Et pour les boucles ? Là, la différence devrait exister !

\n\n

Le plus souvent, le débat s’enflamme autour des boucles. Comparez les deux approches :

\n\n
// Variante 1 : avec <\nfor (int i = 0; i < n; ++i) {\n    // faire quelque chose\n}\n\n// Variante 2 : avec <=\nfor (int i = 0; i <= n - 1; ++i) {\n    // faire la même chose\n}
\n\n

L’intuition suggère : la deuxième variante effectue un calcul supplémentaire n - 1. Mais regardons ce qui se passe après l’optimisation par le compilateur.

\n\n

Lançons un benchmark avec g++ -O2 pour n = 1 000 000 000 :

\n\n
#include <iostream>\n#include <chrono>\n\nint main() {\n    const long long n = 1'000'000'000;\n    volatile long long sink = 0; // pour que le compilateur ne supprime pas la boucle\n\n    auto start = std::chrono::high_resolution_clock::now();\n    \n    for (long long i = 0; i < n; ++i) {\n        sink += i;\n    }\n    \n    auto end = std::chrono::high_resolution_clock::now();\n    std::cout << "Temps (<) : " \n              << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()\n              << " ms\\n";\n\n    start = std::chrono::high_resolution_clock::now();\n    \n    for (long long i = 0; i <= n - 1; ++i) {\n        sink += i;\n    }\n    \n    end = std::chrono::high_resolution_clock::now();\n    std::cout << "Temps (<=) : " \n              << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()\n              << " ms\\n";\n\n    return 0;\n}
\n\n

Résultats sur ma machine (i7-107

Blogs

Book Recommendations