11
votes

C pointeurs vs accès membre direct pour les structures

dise que j'ai une structure comme si suit ... XXX PRE>

... et j'ai une variable globale de ce type (je suis bien conscient des pièges des globaux, ceci est pour un système intégré que je n'ai conçu et pour lequel ils sont un mal malheureux mais nécessaire.) Est-il plus rapide d'accéder aux membres de la structure directement ou d'un pointeur? IE P>

double LocalSpeed = pMyGlobal->MaxSpeed;


2 commentaires

Qu'est-ce qu'un pointeur vous fournit cet accès direct ne pas? Et un pointeur est plus lent.


-1 Pour poser une question de micro-optimisation sans l'analyse d'abord.


9 Réponses :


1
votes

Je suppose que, si cela fait une différence du tout, cela serait dépendant de l'architecture.


0 commentaires

21
votes

En général, je dirais aller avec la première option:

double LocalSpeed = MyGlobal.MaxSpeed;


5 commentaires

Je suis avec Reed ici. Le référencement direct est plus sûr, ne nécessite pas de chèque nulle et enregistre une opération de déséroférence. Le contenu de la mémoire de la variable doit être consulté de toute façon, alors pourquoi faire une recherche supplémentaire. Un pointeur ne vous gagne rien si vous avez déjà un accès direct à la variable.


En ce qui concerne la dermeférance du pointeur, c'est ce que j'avais pensé, c'est juste une longue période depuis que je devais faire face à C ou C ++. Merci gars pour vos conseils.


Je l'ai dit depuis que je ne crois pas que cela ne peut pas être répondu sans spécifier l'architecture que la réponse est significative. Voir la réponse d'Ivan, par exemple.


À moins que l'architecture et le compilateur soient entièrement morts, l'accès direct sera au pire identique. Très probablement, Myglobal sera transformé en une seule adresse statique. Dans le pire des cas, le compilateur utilisera un pointeur sur le global.


@plinth: Ce n'est que vrai (et possible) s'il s'agit d'un pointeur de const, car sinon, le pointeur pourrait être réaffecté. Vous allez garder la désarférence en place dans presque tous les compilateurs que j'ai vus. Je suis d'accord, en ce que la différence est au mieux sans signification, mais elle devrait techniquement être une opération plus rapide.



1
votes

en C, il ne devrait y avoir aucune différence, ni une performance insignifiante touchée.

Les étudiants C sont enseignés: xxx

Vous devriez pouvoir comparer le démontage de Les deux pour vous convaincre qu'ils sont essentiellement les mêmes, même si vous n'êtes pas un programmeur de code de montage.

Si vous recherchez une optimisation de la performance, je regarderais ailleurs. Vous ne pourrez pas enregistrer suffisamment de cycles de processeur avec ce type de micro-optimisation.

Pour des raisons stylistiques, je préfère la notation de la structure-point, en particulier lors de la gestion de singleton-globaux. Je trouve beaucoup plus propre à lire.


2 commentaires

La question ne concerne pas -> VS *, il s'agit d'utiliser un pointeur en premier lieu.


La question est la suivante: "Est-il plus rapide d'accéder aux membres de la structure directement ou via un pointeur?" Je crois que j'ai abordé la question.



8
votes

Le premier devrait être plus rapide car il ne nécessite pas de désherbage du pointeur. Ensuite encore, c'est vrai pour les systèmes basés sur X86, pas sûr pour les autres.

sur x86 Le premier traduirait quelque chose comme celui-ci xxx

et le second serait quelque chose comme ceci xxx


0 commentaires

1
votes

En général, l'accès à la structure directement serait plus rapide, car il ne nécessitera pas de déréférence supplémentaire du pointeur. La désarférence du pointeur signifie qu'il doit prendre le pointeur (la chose dans la variable), charger tout ce qu'il pointe, puis opérer dessus.


0 commentaires

3
votes

sur votre plate-forme intégrée, il est probable que l'architecture soit optimisée de manière à ce qu'il s'agisse essentiellement d'un lavage, et même si ce n'était pas, vous ne remarqueriez jamais un impact sur la performance si cela a été exécuté dans une boucle très serrée.

Il y a probablement beaucoup plus de zones de performance plus évidentes de votre système.


0 commentaires

3
votes
    data.first = 9.0;
008D1000  fld         qword ptr [__real@4022000000000000 (8D20F0h)] 

    pData->second = 10.0;
008D1006  xor         eax,eax 
008D1008  fstp        qword ptr [data (8D3378h)] 
008D100E  fld         qword ptr [__real@4024000000000000 (8D20E8h)] 
008D1014  fstp        qword ptr [data+8 (8D3380h)] 

3 commentaires

Maintenant cibler sa plate-forme intégrée.


Quels ont été les paramètres d'optimisation?


C'est faux. Votre premier membre gagnera toujours par définition d'une structure (le pointeur d'une structure est également un pointeur d'un premier membre). Vous devriez comparer deuxième vs seconde.



2
votes

Démontez, démontez, démontez ...

Selon les lignes de code, vous ne nous affichez pas, il est possible que si votre pointeur est un peu statique, un bon compilateur saura cela et pré-calculez l'adresse pour les deux. Si vous n'avez pas d'optimisations pour que toute cette discussion est muette. Cela dépend également du processeur que vous utilisez, les deux peuvent être effectuées avec une seule instruction en fonction du processeur. Donc, je suis sur les étapes d'optimisation de base: p>

1) démonter et examiner 2) Temps d'exécution p>

Comme mentionné ci-dessus, bien que la ligne de fin soit peut-être un cas de deux instructions au lieu d'un coût unique d'un seul cycle d'horloge que vous ne verriez probablement jamais. La qualité de vos choix de compilateur et d'optimisation va faire des différences de performance beaucoup plus dramatiques que d'essayer de modifier une ligne de code dans l'espoir d'améliorer la performance. Les compilateurs de commutation peuvent vous donner 10 à 20% dans les deux sens, parfois plus. Comme cela peut modifier vos drapeaux d'optimisation, tout ce qui est sur le code le plus rapide, parfois -O1 fonctionne mieux que -O3. P>

Comprendre ce que ces deux lignes de code produisent et comment maximiser les performances de la langue de haut niveau vient de la compilation de différents processeurs et de désassemblage à l'aide de divers compilateurs. Et plus important encore, le code autour des lignes en question joue un rôle important dans la manière dont le compilateur optimise ce segment. P>

Utiliser l'exemple de quelqu'un d'autre sur cette question: p>

mov r3, #9
str r3, [r2, #0]

mov r3, #10
str r3, [r2, #4]


2 commentaires

Utiliser des doubles au lieu d'INT signifie que plus de registres Le magasin lui-même est toujours une seule instruction pour le pointeur ou l'accès direct. Il n'ya toujours aucune différence, pour ce compilateur pour ce processeur pour cette session de compilation.


C'est faux. Votre premier membre gagnera toujours par définition d'une structure (le pointeur d'une structure est également un pointeur d'un premier membre). Vous devriez comparer deuxième vs seconde.



0
votes

L'accès aux membres directs est plus rapide (pour les pointeurs que vous obtiendrez une opération de désarence de pointeur de plus, typiquement). Même si j'ai du mal à l'imaginer dans une situation où ce serait un problème, une performance ou autre.


0 commentaires