in c #, lors de la définition d'une valeur de variable booléenne sur Assumer la variable est Méthode 1, Vérification d'abord: forte> p> ou méthode 2, il suffit de le régler: strong> p> false code> seul em> quand il est
vrai code>, dois-je vérifier s'il est
VRAI CODE> Avant de le définir ou simplement la définir?
vrai code> 50% du temps, vérifiant qu'il est logique car une comparaison est plus rapide. Si la variable est
vrai code> la plupart du temps, dois-je simplement ignorer la comparaison? P>
Quelle est la meilleure pratique? H2>
9 Réponses :
Ne compliquez pas la vie. Il suffit de le mettre. En fait plus cher à vérifier en premier, de toute façon, puisque vous devez maintenant supprimer la valeur existante de RAM (ou cache) avant d'envoyer une nouvelle valeur. P>
(avec grâce à Colin MacKay ...) Les tests incitent d'abord également des sanctions de stands de pipeline en raison de la branche des prédictions erronées. P>
Il y avait une question commençait à l'origine par le nouveau code qui a maintenant été supprimé. La question était de savoir pourquoi si des déclarations sont plus chères. Ma réponse: Si des déclarations impliquent une opération de saut dans le processeur. Les opérations de saut signifient que le processeur doit vider son pipeline d'instructions à venir pour passer au nouvel ensemble d'instructions. (Si je comprends bien, je ne suis pas un expert de processeur)
Parce que vous devrez peut-être faire glisser la vieille valeur de la RAM, ce qui étalait la CPU pour des centaines de cycles, alors que simplement définir la valeur allait généralement directement au cache L1 avec une latence minimale.
Vérification d'abord signifie que la valeur n'est pas toujours modifiée. La fréquence des modifications dépend de la valeur la plus probable de la variable. Disons dans mon cas bvariable code> est rarement vrai, puis définir la valeur semble gaspillée. Je suis d'accord que dans 99% des cas, cela sera une optimisation prématurée, mais si elle doit être effectuée pour chaque enregistrement dans un ensemble énorme i> ensemble de données qui couvre plusieurs pages?
@Marcelo: Je ne suis pas aussi bien informé sur la mise en cache du processeur, mais pourquoi la définition de la valeur serait-elle moins aérienne que de le vérifier? Ne définirait pas la valeur être aussi intensive, sinon plus?
@FreshCode: Vous semblez déterminé à conclure que les tests d'abord sont meilleurs, vous devriez donc simplement écrire le code et voir par vous-même. Qui sait? Peut-être que vous allez prouver que la sagesse établie ne va pas.
@Marcelo: L'intuition me dit que la vérification est meilleure, c'est mieux, mais je n'aurais pas demandé si j'avais confiance à mon intuition :). Je n'ai pas le temps de le tester correctement, je voudrais donc connaître la meilleure pratique, qui devrait prendre en compte le travail avec d'énormes ensembles de données.
Comme d'autres l'ont dit, vous optimisez prématurément. Et souvent, cela conduit à des solutions plus lentes en raison de la façon dont l'architecture sous-jacente fonctionne n'est pas toujours intuitive. La pipeline de processeur, par exemple, est idéale pour accélérer la manière dont le processeur gère les instructions, mais les opérations de saut signifie que la pipelle est pleine d'instructions qui ne peuvent pas être utilisées car le flux a déplacé ailleurs.
L'explication de l'opération de saut a du sens. Peut-être ajouter cela à votre réponse, Marcelo?
@FreshCode: Pour répondre plus directement à votre question, l'accès à la RAM est des centaines de fois plus lents que tout ce qui se passe sur la matrice de la CPU. Ainsi, lorsque vous devez chercher une valeur de RAM, il y a de bonnes chances que vous encouragez une performance massive, même Si seulement 5% de ces accès se révèlent inutiles. Lors de la rédaction de données, toutefois, la sortie sera généralement mise en mémoire tampon dans le cache L1, qui est sur le même déique que le noyau de la CPU. En tout état de cause, si vous voulez vraiment serrer le maximum de votre système, il n'ya aucun substitut à la mise en œuvre et à la comparaison des deux options.
@Marcelo: Merci pour l'explication complète. Je n'ai pas réalisé que le réglage au lieu de vérifier ne nécessiterait pas de frapper un bélier.
@FreshCode: C'est May i> ne pas nécessiter un coup de mémoire. Une écriture pourrait remplir le cache et forcer une rubil de RAM avant de pouvoir terminer. Comme @Colin souligne, l'intuition est un guide pauvre dans ce domaine. Je n'étais pas facétieux quand j'ai suggéré que vous prouviez tout le monde tort. Si vous le codez, vous pourriez vous surprendre tous, en raison d'une particularité dans la structure de votre problème. Je dirais que les chances de ce qui se passe sont faibles, cependant.
@Marcelo: Parce que je n'ai aucune vie sociale et je suis un nerd complet, j'ai codé cet exemple et l'a exécuté à l'aide de l'optimisation du compilateur C #. Il est intéressant de noter que "si" l'instruction "si" n'est pas optimisée - bien que tout l'extrait de code est i> si vous n'utilisez pas les valeurs.
@Marcelo: J'ai accepté la réponse de Dave qui mieux élabore une pipeline pour le moment. Vous devez incorporer la discussion de commentaires dans votre réponse.
La seule raison de faire la comparaison est que si vous avez une logique supplémentaire, vous devez exécuter lorsque la valeur change. p>
Si vous ne l'assignez que de toute façon, cela fera probablement la performance si vous faites le chèque supplémentaire. P>
en C # La réponse est la suivante: la méthode 2 est toujours préférée. Comme il s'agit d'une optimisation très simple, si la méthode 1 était vraiment plus rapide, le compilateur le ferait. P>
EDIT: P>
Donald Knuth a des conseils sur votre méthode 1, comme «l'optimisation prématurée est la racine de tout le mal« et le code »est censé être lu par l'homme en premier et les machines secondes». P>
Cela semble être trop important d'une micro-optimisation, je pense vraiment que le compilateur optimise ce bit pour vous quand même. p>
Mais, si vous voulez que la valeur finale soit false code> quoi que ce soit, je suppose simplement l'affecter à
false code> fait plus de sens. Je veux dire pourquoi vérifier si vous n'avez pas vraiment besoin de vous soucier de la valeur de toute façon. P>
L'optimisation prématurée est la racine de tout mal. Il n'y a aucun moyen que vous puissiez persuader que cette "optimisation" vous donnera tout gain de performance em> sur tout p>
Je dirais que la différence de performance est si insignifiante vient de définir la chose à FALSE tout le temps. P>
Si c'est faux, il sera mis à nouveau sur FALSE. Si c'est vrai, il sera défini sur FALSE. P>
à la fin du code, la variable sera fausse, peu importe. P>
En la définissant simplement sur FALSE tout le temps que vous rendez l'intention plus claire de toute façon. Tout le monde en train de lire le code voit instantanément que la valeur sera fausse dans tous les cas d'ici la fin de cette section du code. Bien que si vous avez une déclaration de si, ils devront y penser un peu plus fort. P>
Pour la maintenance seule, je préconiserais la définition de la valeur à FALSE, quelle que soit sa valeur initiale car elle sera toujours fausse à la fin. P>
Le problème de performance n'est pas pertinent ici, car une simple déclaration si celle-ci est essentiellement proche d'un NO-OP pour le processeur. Il est beaucoup plus important que votre code communique clairement son intention de lecteurs ultérieurs! P>
Thomas p>
Qu'est-ce qui vous fait penser que la comparaison est plus rapide? Si le code que vous écriviez a été effectué dans un compilateur C, l'instruction IF serait divisée en au moins deux instructions - une instruction de comparaison / ramification et une instruction "définie" sur un seul mot sur un seul mot. p>
Le "Set" compilerait à une seule instruction. Votre «optimisation» pourrait éventuellement rendre votre programme à courir plus lentement et que votre programme soit moins lisible. Il suffit de définir la variable et n'essayez pas de dépasser de petites choses. p>
Les CPU ne sont pas comme des bases de données. Vous ne payez pas une pénalité élevée pour les modifications de données. Strong> Vous payez des sanctions élevées pour effectuer des voyages à la mémoire principale et pour la ramification (si des déclarations). Les succursales coûtent les performances des coûts car Pipelining Les CPU commencent réellement à exécuter des instructions après em> la succursale avant Les instructions de la branche prennent même leur décision! (Je sais que cette déclaration est quelque peu inquiet). Mais ce que cela signifie, c'est que la CPU doit dépenser des ressources " deviner " Quel est le résultat de votre si déclaration va être. Si cela devine mal, il doit "jeter" les résultats de toutes les instructions qu'elle devinait serait exécutée après la branche et réessayer. C'est mauvais. C'est pourquoi les branches sont chères. p>
La morale de cette histoire particulière n'est pas que vous ne devriez jamais optimiser, mais que vous devriez Ne jamais optimiser sans comprendre complètement les implications de votre optimisation forte>. Dans ce cas, vous étiez parti avec l'option 1, vous pouvez éventuellement vous retrouver avec une application plus lente qui est moins lisible pour démarrer. p>
En fait, si vous êtes vraiment intéressé par ce genre de chose, vous devriez
J'ai entendu de bonnes choses sur le code complet et je vais certainement le vérifier.
Méthode 2 devrait être préférable simplement parce qu'il exprime le même résultat plus simplement, ce qui facilite la lecture, car d'autres l'ont dit - pour quelque chose de simple comme cette lisibilité est beaucoup plus importante que la préoccupation de performance disparaissante. P>
Cependant, il est possible que bvariable code> pourrait être une propriété, dans laquelle le réglage de cas pourrait entraîner d'autres effets secondaires - à la fois en termes de performances et de résultats, potentiellement. P>
Optimisation prématurée. Optimisation inutile.
Vous ne le savez pas. Si la première priorité est la lisibilité, alors vérifiez d'abord être plus facile à comprendre dans le contexte.
Dans ce scénario et 99,9% des autres comme celui-ci, plus vite n'est pas pertinent. Il suffit de la définir sur False tant que vous n'avez pas besoin d'effectuer une autre logique conditionnelle.
Je suppose que la réponse dépend de nombreux facteurs, y compris le processeur lui-même (pipelining, le coût d'une prévision de branche manquée, mise en cache, etc.). Avez-vous essayé de comparer cela? Je suppose également que cela sera une optimisation prématurée (et inutile) dans votre cas, mais je pense que la question est intéressante d'un point de vue scientifique (purement) scientifique.
C'est une variable. Donc je faire b> le savoir. Si c'était une propriété avec des effets secondaires possibles, ce serait une autre histoire.