8
votes

Déplacer efficacement une classe avec des pods

Comment déplacer efficacement une classe avec un grand ensemble de membres de la pod? Exemple:

struct{
    int a1;
    int a2;
    int a3;
    ...
    ...
    ...
};


2 commentaires

Je ne pense pas que cela ne soit plus rapide qu'une simple affectation.


S'il vous est possible de stocker tous ces éléments dans un tableau, allouez de manière dynamique et volez le pointeur. Sinon, l'affectation est probablement votre meilleure mise.


4 Réponses :


15
votes

Les pods ne bougent pas, ils suffisent simplement. Parce qu'il n'y a pas d'indirection. Donc, utilisez simplement une affectation ordinaire et demandez au compilateur d'optimiser l'efficacité de votre efficacité. N'oubliez pas de mesurer systématiquement (quoi sur Terre vous faites différemment) et après. Considérez également si le temps de programmeur gaspillé, qui est de l'argent, vaut la micro-optimisation.


2 commentaires

Lorsque vous dites "Demandez au compilateur d'optimiser l'efficacité" Que voulez-vous dire autre que d'utiliser en ligne ?


@johnbakers Je crois, l'auteur signifiait "-O3" et tel.



8
votes

Vous devez apporter un jugement d'ingénierie pour jouer. Imaginez pour un exemple que vous parlez de savoir s'il faut utiliser un std :: Array ou un std :: vecteur avec n éléments, où n est une constante de la compilation.

Quand n est très petit, std :: Array est le gagnant clair car il n'y a pas d'allocation de tas. Et des copies (et des mouvements équivalents à des copies) sont bon marché.

Lorsque n est très grand, std :: vecteur est le gagnant clair car, bien qu'il existe une allocation de tas, et on peut se déplacer autour du Vecteur avec le coût de la version seulement 3 mots, quelle que soit la taille de n .

Lorsque n == 3 , il ne fait aucun doute que c'est le meilleur choix. Quand n == 3 000 000 Il ne fait aucun doute que c'est le meilleur choix.

Votre travail, comme le concepteur, consiste à entrer dans cette zone grise entre ces deux extrêmes et prendre la bonne décision. Il n'y a pas de décision toujours juste. Les mesures de performance contre vos affaires d'utilisation attendues vont très loin. Utilisez pour ces mesures de performance. Si vous ne savez pas ce que est, recherche Stackoverflow.


0 commentaires

14
votes

Cette question trahissait un manque de compréhension de ce que le mouvement en C ++ 11 est pour.

Lorsque vous copiez un objet comportant des pointeurs ou possédant autrement des ressources, il existe deux façons de faire cette copie. Vous pouvez soit copier les références de pointeur / ressources, ou vous pouvez attribuer de nouveaux objets / ressources et copier la valeur des originaux dans les nouvelles.

Dans le premier cas, vous êtes laissé avec deux objets qui ont des références à l'objet même . QT fait-il beaucoup. Si vous utilisez un objet pour modifier quelque chose que vous référencez, vous modifiez également l'autre. Vous avez généralement besoin d'une sorte de compteur de référence afin de ne pas doubler - supprimer le pointeur ou à double libération de la ressource.

Dans le second cas, vous êtes laissé avec deux objets complètement séparés. Ceci est communément appelé "Semantitique de la valeur", car si vous copiez une pod en une autre, vous avez deux objets complètement séparés après. Changer on ne change pas un autre.

Déplacer la sémantique sont un mécanisme C ++ 11 pour permettre aux objets qui ont normalement une sémantique de valeur pour avoir une sémantique de référence dans certaines conditions. Il permet essentiellement un objet de voler les pointeurs / ressources référencés par une autre instance d'objet.

Par exemple, prenez std :: vecteur ; Ceci est juste un wrapper autour d'un tableau alloué de manière dynamique et redimensionnée. Comme avec la plupart des objets de la bibliothèque standard C ++, Vecteur implémente la sémantique de la valeur. Si vous copiez un vecteur , le nouveau vecteur doit allouer un nouveau tableau et copier chaque élément de l'ancien dans le nouveau. Une fois que vous avez terminé, vous avez deux tableaux complètement séparés.

Déplacer la sémantique est un moyen de transférer le tableau contenu dans un vecteur dans un autre. Après l'opération, l'objet Source de déplacement est "vide" (techniquement dans un état non défini, mais il est effectivement séparé des données qu'il attribuées). Le nouveau vecteur a maintenant le même pointeur que l'ancien vecteur a fait; Le nouveau vecteur supprimera la mémoire qu'elle n'a pas alloué.

Comme vous pouvez le constater, tout est basé sur le concept d'un objet propriétaire de ressources. vecteur alloue et possède un tableau; C'est destructeurs la détruire. C'est comme ça que vous définissez la propriété. Le mouvement est sur transférer la propriété .

Les pods ne peuvent pas exprimer la propriété des pointeurs ou des ressources, car les pods doivent avoir des destructeurs triviaux (c'est-à-dire: destructeurs qui ne font rien). Parce que les pods ne peuvent pas exprimer la propriété, il n'y a rien à déplacer . Vous ne pouvez pas transférer la propriété entre les objets s'ils ne possèdent rien.


0 commentaires

2
votes

Faites une classe à pointer vers la classe avec des pods et utilisez STD :: Déplacer sur le premier.


0 commentaires