J'ai vu des commentaires sur ce que " J'aimerais savoir pourquoi est-ce le cas. Pourriez-vous montrer un exemple dans ASM? P> Merci! :) p> EDIT: P> Source p> Voici ce qu'il a fait. p> <> code> est plus rapide que
= code>" ou "
! = code> plus vite que
= = code> "dans un
si () code> instruction.
12 Réponses :
J'aurais prétendre que cela est à plat tort, sauf peut-être dans des circonstances très spéciales. Les compilateurs peuvent refroidir un dans l'autre sans effort (en activant simplement le si code> et
sinon code> cas). P>
Si vous pouvez fournir un petit exemple qui montre clairement une différence, je suis sûr que la communauté de dépassement de la pile pourrait expliquer pourquoi. Cependant, je pense que vous pourriez avoir des difficultés à construire un exemple clair. Je ne pense pas qu'il y aura une différence de performance notable à une échelle raisonnable. P>
Je suis désolé, vous pouvez le voir maintenant.
Ce n'est pas un exemple que je peux compiler et courir (même si j'avais Delphi).
@ Greg, sa seule ligne seulement. Si (0xFF! = 255) retour; ou si (256 = $ fe) retour;
Oui, je vois ça, mais je ne vois pas la preuve qu'il y a une différence du tout.
Je doute fortement qu'il y ait une différence de vitesse. Pour des types intégrés, par exemple, vous obtenez une instruction CMP et que JZ (saut si zéro) ou Jnz (saut si pas zéro), selon que vous utilisiez = ou ≠. Il n'y a pas de différence de vitesse ici et je m'attendrais à ce que cela soit aussi vrai à des niveaux plus élevés. P>
spontané cependant; La plupart des autres choses de votre code affecteront les performances plus que le choix entre == et! = (ou = et <> en fonction de la langue). P>
Lorsque j'ai dirigé un test en C # sur plus de 1000000 itérations de chaînes comparatives (contenant l'alphabet, A-Z, avec les deux dernières lettres inversées dans l'une d'entre elles), la différence était comprise entre 0 et p> P>
Il a été dit avant: écrivez le code de lisibilité; Changement en code plus performant quand il a été établi qu'il faudra une différence em>. p>
Modifier: répété le même test avec des tableaux d'octets; même chose; La différence de performance est négligeable. P>
Je prétendrais que c'était un faux arrêt à plat. Le test d'égalité est toujours le même que le test d'inégalité. Avec une chaîne (ou des tests de structure complexes), vous allez toujours casser exactement le même point. Jusqu'à ce que ce point de rupture soit atteint, la réponse à l'égalité est inconnue. p>
Si vous regardez l'IL du mais le Je dirais que la performance est la même, avec peut-être une petite performance (très petite, très très petite) pour la déclaration ==. Mais je crois que le compilateur Optimizer & Jit supprimera ceci. P> string.op_equality Code> et
string.op_inequalité CODE> Méthodes, vous verrez que les deux internall appellent String.equals. P>
op_inequalité code> invertit le résultat. Ceci est deux déclarations IL plus. P>
Votre dernière phrase est importante: ce que vous avez vu dans IL peut n'avoir aucune incidence sur le code éventuellement exécuté.
Mais il faudra 2 déclarations il plus à JIT (ou pré-jit, et optimiser) 4 octets plus à charger, etc. Si vous mettez cela ensemble ... ;-)
Cette liste (en supposant qu'il est sur X86) des instructions de l'ASM pourrait aider: p>
(non-responsabilité, je n'ai rien de plus que l'expérience très basique avec l'assembleur d'écriture afin que je puisse être hors de la marque) em> p>
Cependant, cela dépend évidemment des instructions de montage du compilateur Delphes. Sans voir cette sortie, il s'agit de devinettes. Je vais garder ma citation de Donald Knuth en tant que responsable de ce genre de chose pour tous, sauf un jeu d'applications de niche (jeux, appareils mobiles, applications de serveur haute performance, logiciels de sécurité, lance-missiles, etc.) est la chose que vous s'inquiéter de la dernière fois à mon avis. P>
"Nous devrions oublier petit
Généralités, disons environ 97% de la
TEMPS: L'optimisation prématurée est la
racine de tout mal. " p>
blockQuote>
Si vous écrivez un de ceux-ci ou similaire, alors évidemment, vous vous souciez, mais vous ne l'avez pas spécifié. P>
Qu'est-ce que cela a à voir avec la question? Si un opérateur était I> plus rapide que l'autre, cela serait essentiel de savoir à cause des implications pour l'architecture et comment nous devrions écrire du code. Même une telle micro-optimisation serait utile si elle était appliquée de manière cohérente.
Votre réponse contredit votre commentaire
Eh bien, cela pourrait être ou ça ne pouvait pas être, c'est la question suivante :-) La chose est que cela dépend de la langue de programmation que vous utilisez. Étant donné que toutes vos déclarations finiront par finir par des instructions à la CPU, celle qui utilise le moins d'instructions pour atteindre le résultat sera la plus rapide. P>
Par exemple, si vous dites que les bits x sont égaux aux bits y, vous pouvez utiliser l'instruction qui utilise un xor utilisant les deux bits comme une entrée, si le résultat est autre que 0, il n'est pas le même. Alors, comment sauriez-vous que le résultat est autre que 0? En utilisant l'instruction qui retourne true si vous dites que l'entrée A est supérieure à 0. p>
C'est déjà 2 instructions que vous utilisez pour le faire, mais comme la plupart des CPU ont une instruction qui se compare en un seul cycle, il s'agit d'un mauvais exemple. P>
Le point que je fais est toujours le même, vous ne pouvez pas faire ces déclarations généralement sans fournir le langage de programmation et l'architecture de la CPU. P>
Cela pourrait avoir quelque chose à voir avec la prédiction des succursales sur la CPU. La prédiction des succursales statiques prédirait qu'une succursale ne serait tout simplement pas prise et récupérerait la prochaine instruction. Cependant, presque personne ne l'utilise plus. Autre que cela, je dirais que c'est taureau parce que les comparaisons doivent être identiques. P>
Juste deviner, mais vous souhaitez conserver la logique, vous ne pouvez pas simplement remplacer avec p> pour conserver la logique , le code d'origine doit avoir été quelque chose comme p> ou p> et qui peut vraiment être un peu plus lentement que le test sur l'inégalité. p> p>
Les deux sont cmp suivis d'une branche. Je ou jne. Et presque tous les processeurs ont un drapeau zéro et des moyens de le tester.
Il peut être optimisé par le compilateur, mais "non (a = b)" semble être un peu plus de travail que "A <> B". Bien que le premier est un comparateur suivi d'une négation, le second est un comparateur seulement. Je ne suis pas sûr de la version "sinon", cependant.
Cela pourrait également résulter d'une interprétation erronée d'une expérience. P>
La plupart des compilateurs / optimiseurs supposent qu'une succursale est prise par défaut. Si vous inverser l'opérateur et l'ordre IF-alors-alors, et la succursale qui est maintenant prise est la clause de l'autre, cela pourrait provoquer un effet de vitesse supplémentaire dans le calcul hautement en calcul (*) p>
(*) Évidemment, vous devez faire beaucoup d'opérations pour cela. Mais cela peut être important pour les boucles les plus strictes par ex. codecs ou analyse d'image / vision de la machine où vous avez 50 Mo / s de données au chalut. .... Et puis je ne sois même que sur ce niveau pour le code vraiment réutilisable. Pour le code d'entreprise ordinaire, cela ne vaut pas la peine. P>
Je pense qu'il y a une certaine confusion dans votre question précédente sur ce que l'algorithme était que vous essayiez de mettre en œuvre, et donc dans ce que le" spef-up "prétendait faire.
Voici un démontage de Delphi 2007. Optimisation sur. (Remarque, Optimisation a changé le code un peu, mais pas de manière pertinente. P>
Unit70.pas.31: for I := 0 to 100 do 004552B5 33C0 xor eax,eax Unit70.pas.33: if i = j then 004552B7 3B02 cmp eax,[edx] 004552B9 7506 jnz $004552c1 Unit70.pas.34: k := k+1; 004552BB FF05D0DC4500 inc dword ptr [$0045dcd0] Unit70.pas.35: if i <> j then 004552C1 3B02 cmp eax,[edx] 004552C3 7406 jz $004552cb Unit70.pas.36: l := l + 1; 004552C5 FF05D4DC4500 inc dword ptr [$0045dcd4] Unit70.pas.37: end; 004552CB 40 inc eax Unit70.pas.31: for I := 0 to 100 do 004552CC 83F865 cmp eax,$65 004552CF 75E6 jnz $004552b7 Unit70.pas.38: end; 004552D1 C3 ret
Veuillez fournir un lien vers l'un de ces commentaires.
Spéculation pure, à moi
@John Si c'est vrai, et il n'y a aucune preuve dans le code que c'est, c'est un bogue dans le compilateur Delphi. La comparaison de deux octets est typiquement la même instruction de la machine, que vous soyez ensuite sur l'égalité ou l'inégalité.
Cette question reste inconnue pour le moment. Je suis avéillé quiconque qui a essayé de le prouver le trual ou le vrai. J'apprécie les réponses que vous m'avez données et que je ne regrette pas que je me demandais ici. :)
Pourquoi ne demandez-vous pas de demander à l'auteur de ces mots?
Réponse courte: Certains processeurs ont le foo! = Null A.K.A. FOO! = 0 Comparaison optimisée.
J'ai entendu le moins de temps qu'un processeur est devenu plus rapide, il devient quelque chose à faire avec des électrons devenant en forme.