Lequel est le plus rapide: while(1) ou while(2)?

il s'agissait d'une question d'entrevue posée par un cadre supérieur.

ce qui est plus rapide?

while(1) {
    // Some code
}

ou

while(2) {
    //Some code
}

j'ai dit que les deux ont la même vitesse d'exécution, comme l'expression à l'intérieur de while devrait finalement évaluer à true ou false . Dans ce cas, les deux évaluent à true et il n'y a aucune instruction conditionnelle supplémentaire à l'intérieur de la condition while . Ainsi, les deux seront d'avoir la même vitesse d'exécution et je préfère tout (1).

mais l'intervieweur a dit avec confiance: "Vérifiez vos bases. while(1) est plus rapide que while(2) ." (Il n'était pas test ma confiance)

Est-ce vrai?

Voir aussi: Est "for(;;)" plus rapide que le "while (TRUE)"? Si non, pourquoi les gens utilisent-ils?

557
demandé sur Community 2014-07-20 11:32:49

22 réponses

les deux boucles sont infinies, mais nous pouvons voir lequel prend plus d'instructions/ressources par itération.

en utilisant gcc, j'ai compilé les deux programmes suivants pour assembler à différents niveaux d'optimisation:

int main(void) {
    while(1) {}
    return 0;
}



int main(void) {
    while(2) {}
    return 0;
}

même sans optimisations ( -O0 ), l'assemblage généré était identique pour les deux programmes . par conséquent, il n'y a pas de différence de vitesse entre les deux boucles.

pour référence, voici l'assemblage généré (en utilisant gcc main.c -S -masm=intel avec un drapeau d'optimisation):

avec -O0 :

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 32
    .seh_stackalloc 32
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

avec -O1 :

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

avec -O2 et -O3 (même sortie):

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .section    .text.startup,"x"
    .p2align 4,,15
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

en fait, l'assemblage généré pour le la boucle est identique pour tous les niveaux d'optimisation:

 .L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

Les choses importantes étant:

.L2:
    jmp .L2

Je ne peux pas très bien lire assembly, mais c'est évidemment une boucle inconditionnelle. L'instruction jmp réinitialise inconditionnellement le programme à l'étiquette .L2 sans même comparer une valeur à true, et bien sûr immédiatement le fait à nouveau jusqu'à ce que le programme soit en quelque sorte terminé. Cela correspond directement à la Code C/C++:

L2:
    goto L2;

Edit:

assez intéressant, même avec aucune optimisations , les boucles suivantes ont toutes produit la même sortie exacte (inconditionnel jmp ) dans l'assemblage:

while(42) {}

while(1==1) {}

while(2==2) {}

while(4<7) {}

while(3==3 && 4==4) {}

while(8-9 < 0) {}

while(4.3 * 3e4 >= 2 << 6) {}

while(-0.1 + 02) {}

et même à mon étonnement:

#include<math.h>

while(sqrt(7)) {}

while(hypot(3,4)) {}

les choses deviennent un peu plus intéressantes avec les fonctions définies par l'utilisateur:

int x(void) {
    return 1;
}

while(x()) {}



#include<math.h>

double x(void) {
    return sqrt(7);
}

while(x()) {}

à -O0 , ces deux exemples appellent x et effectuent une comparaison pour chaque itération.

premier exemple (renvoi 1):

.L4:
    call    x
    testl   %eax, %eax
    jne .L4
    movl    "1519120920", %eax
    addq    , %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

deuxième exemple (renvoi sqrt(7) ):

.L4:
    call    x
    xorpd   %xmm1, %xmm1
    ucomisd %xmm1, %xmm0
    jp  .L4
    xorpd   %xmm1, %xmm1
    ucomisd %xmm1, %xmm0
    jne .L4
    movl    "1519130920", %eax
    addq    , %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

cependant, à -O1 et au-dessus, ils produisent tous les deux le même ensemble que les exemples précédents (un jmp retour à l'étiquette précédente).

TL; DR

sous GCC, les différentes boucles sont compilées pour un assemblage identique. Le compilateur évalue les valeurs constantes et ne prend pas la peine d'effectuer une comparaison réelle.

La morale de l'histoire est:

  • il existe une couche de traduction entre le code source C++ et les instructions CPU, et cette couche a des implications importantes pour performance.
  • par conséquent, la performance ne peut pas être évaluée en regardant seulement le code source.
  • le compilateur devrait être assez intelligent pour optimiser de tels cas triviaux. Les programmeurs ne devraient pas perdre leur temps à penser à eux dans la grande majorité des cas.
658
répondu ApproachingDarknessFish 2018-09-01 11:46:26

Oui, while(1) est beaucoup plus rapide que le while(2) , pour un homme de le lire! si je vois while(1) dans une base de code inconnue, je sais immédiatement ce que l'auteur a voulu, et mes yeux peuvent continuer jusqu'à la ligne suivante.

si je vois while(2) , je vais probablement m'arrêter dans mes traces et essayer de comprendre pourquoi l'auteur n'a pas écrit while(1) . L'auteur du doigt glisser sur le clavier? Ne les responsables de ce code d'utilisation while(n) comme un obscur mécanisme de commentaire pour faire des boucles différentes? Est-ce une solution de rechange grossière pour un avertissement fallacieux dans un outil d'analyse statique cassé? Ou est-ce un indice que je suis en train de lire le code généré? Est-ce un bug résultant d'une trouvaille-et-remplacer-tout mal conseillée, ou une mauvaise fusion, ou un rayon cosmique? Peut-être que cette ligne de code est censée faire quelque chose de radicalement différent. Peut-être était-il supposé lire while(w) ou while(x2) . Je ferais mieux de trouver l'auteur dans l'histoire du dossier. et leur envoyer un email" WTF"... et maintenant j'ai brisé mon contexte mental. Le while(2) pourrait prendre plusieurs minutes de mon temps, alors que while(1) aurait pris une fraction de seconde!

j'exagère, mais juste un peu. La lisibilité du Code est très importante. Et cela vaut la peine d'être mentionné dans une interview!

258
répondu Chris Culter 2014-07-22 05:51:56

les réponses existantes montrant le code généré par un compilateur particulier pour une cible particulière avec un ensemble particulier d'options ne répondent pas entièrement à la question -- sauf si la question a été posée dans ce contexte spécifique ("qui est plus rapide en utilisant gcc 4.7.2 pour x86_64 avec des options par défaut?", exemple.)

en ce qui concerne la définition de la langue, dans la machine abstraite while (1) évalue la constante entière 1 , et while (2) évalue la constante entière 2 ; dans les deux cas, le résultat est comparé pour l'égalité à zéro. La norme linguistique ne dit absolument rien de la performance relative des deux concepts.

je peux imaginer qu'un compilateur extrêmement naïf puisse générer un code machine différent pour les deux formes, du moins lorsqu'il est compilé sans demande d'optimisation.

d'autre part, C Compilateurs absolument doit évaluer certaines expressions constantes au moment de la compilation, lorsqu'elles apparaissent dans des contextes qui nécessitent une expression constante. Par exemple, ceci:

int n = 4;
switch (n) {
    case 2+2: break;
    case 4:   break;
}

nécessite un diagnostic; un compilateur paresseux n'a pas la possibilité de reporter l'évaluation de 2+2 jusqu'au moment de l'exécution. Depuis un compilateur doit avoir la capacité d'évaluer des expressions constantes au moment de la compilation, il n'y a aucune bonne raison de ne pas profiter de cette capacité même si elle n'est pas requise.

the C standard ( N1570 6.8.5p4) dit que

une déclaration d'itération provoque une déclaration appelée corps de boucle d'être exécuté à plusieurs reprises jusqu'à ce que l'expression de contrôle se compare à 0.

de sorte que les expressions constantes pertinentes sont 1 == 0 et 2 == 0 , toutes deux évaluer à la int valeur 0 . (Ces comparaisons sont implicites dans la sémantique de la boucle while ; elles n'existent pas en tant qu'expressions C réelles.)

un compilateur pervers pourrait générer un code différent pour les deux constructions. Par exemple, pour le premier il pourrait générer une boucle infinie inconditionnelle (en traitant 1 comme un cas spécial), et pour le second il pourrait générer une comparaison explicite du temps d'exécution équivalent à 2 != 0 . Mais je n'ai jamais rencontré de compilateur C qui se comporterait de cette façon, et je doute sérieusement qu'un tel compilateur existe.

la plupart des compilateurs (je suis tenté de dire tous les compilateurs de qualité de production) ont des options pour demander des optimisations supplémentaires. Avec une telle option, il est encore moins probable qu'un compilateur générerait un code différent pour les deux formes.

si votre compilateur génère un code différent pour deux constructions, d'abord vérifier si les différentes séquences de code ont effectivement des performances différentes. Si c'est le cas, essayez de compiler à nouveau avec une option d'optimisation (si disponible). S'ils diffèrent encore, soumettez un rapport de bogue au fournisseur du compilateur. Ce n'est pas (nécessairement) un bogue dans le sens d'une non-conformité à la norme C, mais c'est presque certainement un problème qui devrait être corrigé.

Bottom line: while (1) et while(2) presque ont certainement la même performance. Ils ont exactement la même sémantique, et il n'y a aucune bonne raison pour qu'un compilateur ne génère pas du code identique.

et bien qu'il soit parfaitement légal pour un compilateur de générer du code plus rapide pour while(1) que pour while(2) , il est tout aussi légal pour un compilateur de générer du code plus rapide pour while(1) que pour une autre occurrence de while(1) dans le même programme.

(il y a un autre question implicite dans celle que vous avez posée: Comment traitez-vous avec un intervieweur qui insiste sur un point technique incorrect. Ce serait probablement une bonne question pour le site du lieu de travail ).

149
répondu Keith Thompson 2017-05-11 01:50:07

attendez une minute. L'intervieweur, ressemblait-il à ce type?

enter image description here

il est assez mauvais que l'interviewer lui-même a échoué cette interview, que se passe-t-il si d'autres programmeurs de cette entreprise ont "réussi" ce test?

Pas de. Évaluer les énoncés 1 == 0 et 2 == 0 devrait être tout aussi rapide. Nous pourrait imaginer mauvaises implémentations de compilateurs où l'une pourrait être plus rapide que l'autre. Mais il n'y a pas de bon raison pour laquelle l'un devrait être plus rapide que l'autre.

même s'il y a des circonstances obscures où l'affirmation serait vraie, les programmeurs ne devraient pas être évalués sur la base de la connaissance d'obscures (et dans ce cas, flippant) anecdotes. Ne t'en fais pas pour cette interview, le mieux est de s'en aller.

Avertissement: Ce n'est PAS un original de bande dessinée Dilbert. Il s'agit simplement d'un mashup .

131
répondu janos 2014-07-30 08:33:44

Votre explication est correcte. Cela semble être une question qui teste votre confiance en soi en plus de connaissances techniques.

soit dit en passant, si vous avez répondu

les deux morceaux de code sont également rapides, parce que les deux prennent un temps infini pour compléter

l'intervieweur dirait

mais while (1) peut faire plus d'itérations par seconde; pouvez-vous expliquer pourquoi? (ceci est absurde; tester à nouveau votre confiance)

donc, en répondant comme vous l'avez fait, vous avez économisé du temps que vous gaspilleriez autrement à discuter de cette mauvaise question.


voici un exemple de code généré par le compilateur sur mon système (MS Visual Studio 2012), avec des optimisations désactivées:

yyy:
    xor eax, eax
    cmp eax, 1     (or 2, depending on your code)
    je xxx
    jmp yyy
xxx:
    ...

avec optimisations activées:

xxx:
    jmp xxx

donc le code généré est exactement le même, au moins avec un compilateur d'optimisation.

75
répondu anatolyg 2014-07-21 09:07:07

l'explication la plus probable de la question Est que l'intervieweur pense que le processeur vérifie les bits individuels des nombres, un par un, jusqu'à ce qu'il atteigne une valeur non nulle:

1 = 00000001
2 = 00000010

si le " est zéro?"l'algorithme commence du côté droit du nombre et doit vérifier chaque bit jusqu'à ce qu'il atteigne un bit non nul, la boucle while(1) { } devrait vérifier deux fois plus de bits par itération que la boucle while(2) { } .

Cela nécessite un très mauvais modèle mental de la façon dont les ordinateurs fonctionnent, mais il a sa propre logique interne. Une façon de vérifier serait de demander si while(-1) { } ou while(3) { } serait tout aussi rapide, ou si while(32) { } serait plus encore .

58
répondu Ryan Cavanaugh 2014-07-21 14:41:00

bien sûr, je ne connais pas les intentions réelles de ce gestionnaire, mais je propose un point de vue complètement différent: lors de l'embauche d'un nouveau membre dans une équipe, il est utile de savoir comment il réagit aux situations de conflit.

Ils vous ont poussé dans le conflit. Si c'est vrai, ils sont intelligents et la question était bonne. Pour certaines industries, comme la banque, l'affichage de votre problème de débordement de la pile pourrait être une raison de rejet.

mais bien sûr je ne sais pas, je proposez juste une option.

32
répondu Tõnu Samuel 2014-07-22 19:23:12

je pense que l'indice se trouve dans "demandé par un senior manager". De toute évidence, cette personne a cessé de programmer lorsqu'elle est devenue gestionnaire et il lui a fallu plusieurs années pour devenir gestionnaire principal. Jamais perdu l'intérêt pour la programmation, mais jamais écrit une ligne depuis ces jours. Ainsi, sa référence n'est pas "n'importe quel compilateur décent là-bas" comme certaines réponses mentionnent, mais "le compilateur avec lequel cette personne a travaillé il y a 20-30 ans".

à cette époque, les programmeurs ont passé un un pourcentage considérable de leur temps à essayer diverses méthodes pour rendre leur code plus rapide et plus efficace que le temps CPU du "miniordinateur central" était si valable. Tout comme les gens qui écrivaient des compilateurs. Je suppose que le compilateur unique que sa société a mis à disposition à ce moment-là optimisé sur la base de "déclarations fréquemment rencontrées qui peuvent être optimisées" et a pris un peu de raccourci lors de la rencontre un moment(1) et a évalué tout le reste, y compris un moment(2). Ayant eu une telle expérience pourrait expliquer sa position et sa confiance en elle.

la meilleure approche pour vous faire embaucher est probablement celui qui permet au cadre supérieur de se laisser emporter et vous faire la leçon 2-3 minutes sur" les bons vieux jours de la programmation "avant vous en douceur le mener vers le sujet de l'entrevue suivante. (Un bon timing est important ici-trop rapide et vous interrompez l'histoire - trop lent et vous êtes étiqueté comme quelqu'un avec insuffisant concentrer.) Ne lui dis à la fin de l'entrevue que vous serais très intéressé d'en apprendre plus sur ce sujet.

25
répondu OldFrank 2014-07-22 22:30:56

vous auriez dû lui demander comment il en était arrivé à cette conclusion. Sous n'importe quel compilateur décent là-bas, les deux compilent aux mêmes instructions asm. Donc, il aurait dû vous dire le compilateur aussi bien pour commencer. Et même ainsi, vous auriez à connaître le compilateur et la plate-forme très bien pour même faire une hypothèse théorique instruite. Et en fin de compte, cela n'a pas vraiment d'importance dans la pratique, puisqu'il y a d'autres facteurs externes comme la fragmentation de la mémoire ou la charge du système qui influenceront boucle plus que ce détail.

19
répondu Valentin Radu 2014-07-20 08:13:20

pour le plaisir de cette question, je devrais ajouter que je me souviens de Doug Gwyn de la rédaction de comité C que certains compilateurs C tôt sans la réussite de l'optimizer produirait un test en assemblage pour le while(1) (comparer à for(;;) qui ne l'aurait pas).

je répondrais à l'intervieweur en lui donnant cette note historique et en disant que même si je serais très surpris que n'importe quel compilateur ait fait cela, un compilateur aurait pu:

  • sans optimiseur passer le compilateur générer un test pour while(1) et while(2)
  • avec optimizer pass le compilateur est chargé d'optimiser (avec un saut inconditionnel) tous while(1) parce qu'ils sont considérés comme idiomatiques. Cela laisserait le while(2) avec un test et ferait donc une différence de performance entre les deux.

j'ajouterais bien sûr à l'intervieweur que ne pas considérer while(1) et while(2) la même construction est un signe d'optimisation de faible qualité car ce sont des constructions équivalentes.

17
répondu ouah 2014-07-23 11:02:34

une autre façon de répondre à une telle question serait de voir si vous avez le courage de dire à votre gestionnaire qu'il a tort! Et comme tu peux le communiquer doucement.

mon premier instinct aurait été de générer une sortie d'assemblage pour montrer au manager que n'importe quel bon compilateur devrait s'en occuper, et si ce n'est pas le cas, vous soumettrez le prochain patch pour lui:)

9
répondu UncleKing 2014-09-07 22:51:17

pour voir tant de gens plonger dans ce problème, montre exactement pourquoi cela pourrait très bien être un test pour voir à quelle vitesse vous voulez micro-optimiser choses.

ma réponse serait; cela n'a pas beaucoup d'importance, je me concentre plutôt sur le problème d'affaires que nous résolvons. Après tout, c'est pour ça que je vais être payé.

de Plus, j'opterais pour while(1) {} parce qu'il est plus commun, et d'autres coéquipiers pas besoin de passer du temps à comprendre pourquoi quelqu'un ferait pour un chiffre supérieur à 1.

va écrire du code. ;- )

8
répondu Bart Verkoeijen 2014-07-23 07:37:50

j'avais l'habitude de programmer C et le code D'assemblage en arrière quand ce genre de non-sens pourrait avoir fait une différence. Lorsque cela a fait une différence, nous l'avons écrit en assemblée.

si on m'avait posé cette question, j'aurais répété la fameuse citation de Donald Knuth sur l'optimisation prématurée de 1974 et j'aurais marché si l'intervieweur n'avait pas ri et continué.

3
répondu Peter Wooster 2014-07-26 21:55:43

il me semble que c'est une de ces questions d'entrevue comportementale masquées comme une question technique. Certaines entreprises le font - elles poseront une question technique qui devrait être assez facile à répondre pour tout programmeur compétent, mais lorsque la personne interrogée donne la bonne réponse, l'intervieweur leur dira qu'elles ont tort.

La société veut voir comment vous allez réagir dans cette situation. Vous êtes-vous assis là tranquillement et ne poussez pas que votre réponse est correcte, en raison du doute ou de la peur de bouleverser l'intervieweur? Ou êtes-vous prêt à défier une personne en autorité qui tu sais, c'est mal? Ils veulent voir si vous êtes prêt à défendre vos convictions et si vous pouvez le faire avec tact et respect.

3
répondu pacoverflow 2014-07-27 17:32:59

si vous êtes si soucieux d'optimisation, vous devez utiliser

for (;;)

parce qu'il n'y a pas de tests. (cynique) de mode

3
répondu Tom Tanner 2016-03-31 14:39:05

voici un problème: si vous écrivez un programme et mesurez sa vitesse, la vitesse des deux boucles pourrait être différente! Pour une comparaison raisonnable:

unsigned long i = 0;
while (1) { if (++i == 1000000000) break; }

unsigned long i = 0;
while (2) { if (++i == 1000000000) break; }

avec un code ajouté qui imprime l'heure, un effet aléatoire comme la façon dont la boucle est positionnée dans une ou deux lignes de cache pourrait faire une différence. Une boucle peut par hasard être entièrement à l'intérieur d'une ligne de cache, ou au début d'une ligne de cache, ou à cheval sur deux lignes de cache. Et par conséquent, ce que l'intervieweur prétend être le plus rapide pourrait en fait être le plus rapide - par coïncidence.

le pire des scénarios: un compilateur optimisant ne comprend pas ce que fait la boucle, mais constate que les valeurs produites lors de l'exécution de la seconde boucle sont les mêmes que celles produites par la première. Et générer le code complet pour la première boucle, mais pas pour la seconde.

2
répondu gnasher729 2014-07-21 00:34:59

ils sont tous les deux égaux - le même.

selon les spécifications tout ce qui n'est pas 0 est considéré comme vrai, donc même sans aucune optimisation, et un bon compilateur ne générera pas de code pour tout(1) ou de tout(2). Le compilateur générerait un contrôle simple pour != 0 .

2
répondu Nikolay Ivanchev 2014-07-22 19:36:45

à en juger par le temps et les efforts que les gens ont consacrés à tester, à prouver et à répondre à cette question très simple, je dirais que les deux ont été rendus très lents en posant la question.

Et ainsi de passer encore plus de temps sur elle ...

"while (2)" est ridicule, car,

"while (1)", et "while (true)" sont historiquement utilisé pour faire une boucle infinie qui s'attend à "casser" d'être appelé à un certain stade, à l'intérieur de la boucle basée sur une condition qui se produira certainement.

le" 1 "est simplement là pour toujours évaluer à vrai et donc, dire" while (2) "est à peu près aussi stupide que dire" while (1 + 1 = = = 2) " qui évaluera aussi à vrai.

Et si vous voulez être complètement stupide suffit d'utiliser: -

while (1 + 5 - 2 - (1 * 3) == 0.5 - 4 + ((9 * 2) / 4)) {
    if (succeed())
        break;
}

j'aime à penser que votre codeur a fait une typographie qui n'a pas affecté le fonctionnement du code, mais s'il a intentionnellement utilisé le " 2 " juste bizarre alors le sac avant qu'il mette bizarre sh!t tout au long de votre code ce qui rend difficile de lire et de travailler avec.

2
répondu ekerner 2014-07-29 15:33:25

peut-être que l'interviewer a posé une question aussi stupide intentionnellement et voulait que vous fassiez 3 points:

  1. raisonnement de base. les deux boucles sont infinies, il est difficile de parler de performance.
  2. connaissance des niveaux d'optimisation. il voulait avoir de vos nouvelles si vous laissiez le compilateur faire une quelconque optimisation pour vous, cela optimiserait l'état, surtout si le bloc n'était pas vide.
  3. Connaissances sur l'architecture des microprocesseurs. la plupart des architectures ont une instruction CPU spéciale pour comparer avec 0 (mais pas nécessairement plus rapide).
2
répondu Rok Kralj 2014-10-16 06:44:16

cela dépend du compilateur.

si elle optimise le code, ou si elle évalue 1 et 2 à true avec le même nombre d'instructions pour un jeu d'instructions particulier, la vitesse d'exécution sera la même.

Dans les cas réels, il sera toujours aussi rapide, mais il serait possible d'imaginer un particulier compilateur et d'un système particulier, si cela peut être évaluée différemment.

, je veux dire: ce n'est pas vraiment un langue (C) question connexe.

1
répondu user143522 2014-07-23 06:51:08

puisque les gens qui cherchent à répondre à cette question veulent la boucle la plus rapide, j'aurais répondu que les deux compilent également dans le même code d'assemblage, comme indiqué dans les autres réponses. Néanmoins, vous pouvez suggérer à l'intervieweur d'utiliser 'loop unolling'; un Do {} while loop au lieu du while loop.

prudent: vous devez vous assurer que la boucle serait au moins toujours courir une fois .

La boucle doit avoir une condition de rupture à l'intérieur.

aussi pour ce genre de boucle, je préférerais personnellement l'utilisation de do {} while(42) puisque n'importe quel Entier, sauf 0, ferait le travail.

0
répondu 421 2018-01-27 13:58:16

la seule raison pour laquelle le while(2) serait plus lent est:

  1. le code optimise la boucle à

    cmp eax, 2

  2. quand la soustraction se produit, vous êtes essentiellement la soustraction

    un. 00000000 - 00000010 cmp eax, 2

    au lieu de

    B. 00000000 - 00000001 cmp eax, 1

cmp ne définit que les drapeaux et ne définit pas de résultat. Donc sur les bits les moins significatifs nous savons si nous avons besoin d'emprunter ou pas avec b . Alors qu'avec un vous devez effectuer deux soustractions avant d'obtenir un emprunt.

-4
répondu hdost 2014-08-05 17:12:13