7
votes

SHLEN () Compiler l'optimisation du temps

Il y a quelques jours, j'ai découvert que vous pouvez trouver la compilée SHLEN à l'aide de quelque chose comme ceci: xxx

si c'est compilé, alors tout est bon. Vous pouvez ajouter une surcharge telle que: xxx

alors il compilera toujours.

Ma question est - Est-ce que c ++ utilise quelque chose comme ça et si ce n'est pas - pourquoi?


9 commentaires

Si j'utilise char x [3] = {'a', 'B', 'c'}; , cela produirait un résultat inattendu ...


@Kerreksb, ce n'est pas une chaîne de style C.


Char X [10] = "ABC"; est une chaîne C, ce qui produira un résultat inattendu.


Ce ne est pas. Il n'y a pas d'optimisations de la compilation - cela prend beaucoup de place.


"Si je rends mon code plus complexe et obscur, peut-être que le compilateur l'optimise mieux" - en douteux.


bien. Dans des cas spécifiques, mon code fonctionne à coup sûr. Il ne doit y avoir aucun doute à ce sujet. La question est-elle vraiment payée.


ideone.com/ifkuhv et Ideone.com/enokov


COUT << SHLEN _ ("HELLO \ 0WORLD") << "! =" << SHLEN ("HELLO \ 0WORLD") << '\ n'; produit: 11! = 5! = 5! =


Je sais. C'est une abus de l'API et vous ne supposez pas l'utiliser de cette façon. Je travaille avec des cordes de compilation que vous connaissez.


5 Réponses :


3
votes

Votre code est buggy.

La bonne façon de compiler l'optimisation du temps sur SHLEN () code> est, surprenante, appelez simplement SHLEN () CODE>. Compiler moderne comme Clang optimisera l'absence inutile Strlen () code> quand il connaît la longueur au moment de la compilation. p>

aussi, dans la plupart des cas Taille de code> est utile Lorsque vous, le programmeur, utilisez-le correctement avec des chaînes littérales de la variable. Comme: p> xxx pré>

Notez que cela a une hypothèse et si vous le faites, vous vous faites des ennuis, mais pas votre vie simple: p>

const char foo[] = "Hello World\01234";
size_t len = sizeof(foo)-1; // 16


0 commentaires

9
votes

Non, ça ne le fait pas. Parce qu'il donne la mauvaise réponse.

char x[10] = "abc";
int correct_length   = std::strlen(x);  // 3
int incorrect_length = strlen_(x);      // 9


10 commentaires

char x [10] = "ABC"; n'est pas une chaîne constante


@Calvin: Quel est votre point? SHLEN doit fonctionner sur des chaînes constantes et non constantes, et le résultat ne serait pas différent, même si je l'ai fait constamment.


Je pense que le point est que la chaîne de non-const ne correspondrait pas à la const arg dans le modèle - alors seulement quelque chose comme Strlen _ ("ABC") correspondrait et donnerait le bon résultat


@Soren: mal sur les deux comptes.


Nous ne pouvons que compiler l'optimisation du temps sur une chaîne littérale constante quelle longueur est connue au moment de la compilation. Passage non Constry TRAMAY implique que le contenu pourrait disparaître de l'œil du compilateur, qui devrait revenir au traditionnel SHLEN () et n'est pas ce qui ne concerne pas.


@Calvin: Vous ne pouvez pas surcharger sur la base de savoir si quelque chose est une constante de temps de compilation. Même s'il n'y avait pas d'autres problèmes avec cette approche (mentionné dans mon post), la fonction ne peut pas savoir que ce qu'il a est un littéral à chaîne, voire qu'il est en fait const, car vous pouvez faire référence à une référence à un const chose.


Je ne dis pas que c'était une bonne approche, en effet, vous voyez que je suis contre cela comme ma réponse, le code est buggy, même si vous pourriez corriger le code, il s'agit simplement d'un hack inutile pour quelque chose de compilateur pourrait également faire. Mais ensuite, je suppose que l'OP soin de compiler l'optimisation de l'heure de compilation pour Strlen () , que nous nous concentrons sur la chaîne littérale uniquement.


@Calvin n'a pas d'importance, il a un problème avec littéral aussi: "ABC \ 0 CDE"


"ABC \ 0CDE" est différent et je suis d'accord c'est un bogue accepté pour le sujet.


@Calvin: "que nous nous concentrons sur la chaîne littérale uniquement" - Nous ne peut pas Concentrez-vous sur les littéraux de chaînes uniquement. Il n'y a aucun moyen de détecter que ce que vous avez est un littéral à chaîne.



2
votes

Votre SHLEN _ ne fonctionne pas: http://ideone.com/pnneax

Aussi: Je sais pour un fait que Visual Studio 2015 optimise toutes sortes d'appels Strlen , même dans des situations où j'ai eu mes doutes, qui ont été partis quand j'ai vérifié la sortie de l'assembly, qui n'a pas fait Générez Runtime SHLEN appels.

et comme @calvin dit, Clang semble faire de même. Donc, il n'y a vraiment aucune raison pour ça.


2 commentaires

Vous ne comprenez pas comment cela répond à la question?


En fait, il répond à la question



5
votes

Votre Strlen _ renvoie la taille du tableau DATA , pas de la taille d'une chaîne de terminaison NULL. Une implémentation correcte serait la suivante: xxx


3 commentaires

1 up. J'ai délibérément n'a rien dit à propos de cette solution. Cependant, cela ralentira beaucoup si elle sera exécutée au moment de l'exécution. C ++ 17 Permet «Normal» pour la boucle, alors ce sera une solution que je pense.


@Nick sera-ce? Je vois une opportunité d'optimisation de la récupération de la queue ici qui l'équivalait équivalente à la performance à réelle Strlen . Certes, il faudrait une certaine réaménagement du code et je ne sais pas si un compilateur ferait cela.


J'ai oublié que la récursion de la queue C est optimisée pendant des années. Je vais essayer ça.



2
votes

suivi de la réponse ZDF.

J'ai testé et cela semble être une optimisation prématurée. P>

Code: H1>
------------------------------------
|         | GCC       | CLANG      |
------------------------------------
| len     | 0m1.506s  | 0m0.743s   |
| len O3  | 0m0.001s  | 0m0.002s   |
| lenc    | 1m5.476s  | 0m56.871s  |
| lenc O3 | 0m12.267s | 0m0.060s   |
------------------------------------


1 commentaires

Clang et GCC, au moins, sont capables de détecter si la chaîne est déclarée une expression constante (on dirait que ceci est facultatif, non standard) et remplace l'appel à SHLEN avec la longueur de la chaîne. Par conséquent, il n'a aucun sens à s'inquiéter de l'optimisation de la vitesse. Voir ici la sortie de montage.