OVH Cloud OVH Cloud

[débutant] constructeur de copie vs. opérateur d'affectation.

16 réponses
Avatar
cyrcocq
Bonjour,
Soit un objet A de la classe MaClasse
Si on fait
MaClasse B=A

C'est l'opérateur de copie ou d'afectation qui est utilisé?
Ca dépend des cas?

6 réponses

1 2
Avatar
kanze
Fabien LE LEZ wrote:
On Sun, 02 Oct 2005 18:59:56 +0200, James Kanze :

T'es taquin ;-p


N'est-ce pas ? Surtout que chaque fois que quelqu'un propose
la solution avec '=' pour éviter ce problème, je soulève
l'histoire du constructeur de copie privé.


Je reviens sur ce que j'ai dit : tu n'es pas taquin, tu es
sadique ;-)


Moi, ou le langage ?

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Fabien LE LEZ
On Mon, 3 Oct 2005 08:32:00 +0200, "Patrick 'Zener' Brunet"
:

Certes, mais il y a une perte de performance dont il vaut mieux être au
courant


Yep. Ça permet d'optimiser ce que le profiler dit qu'il faut
optimiser...

Avatar
Patrick 'Zener' Brunet
Bonjour.

Je réponds à Fabien LE LEZ
On Mon, 3 Oct 2005 08:32:00 +0200, "Patrick 'Zener' Brunet"
:

Certes, mais il y a une perte de performance dont il vaut mieux être
au courant


Yep. Ça permet d'optimiser ce que le profiler dit qu'il faut
optimiser...


Question de point de vue ;-)

Moi je préfère concevoir (efficace+robuste) d'emblée que corriger ensuite
pour rendre efficace en essayant de ne pas casser la robustesse.
Certes c'est plus complexe, mais ça vaut le coup.

Par ailleurs je joue plutôt dans la cour de l'IA, et donc fais souvent des
codes dont la partie purement calculatoire telle que la voit le profiler
n'est pas le seul élément de décision. C'est difficile de faire l'impasse
sur une conception humaine de l'optimisation dans ce contexte...

C'est vrai qu'on sort alors du tag [débutant] en objet.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/


Avatar
kanze
Patrick 'Zener' Brunet wrote:

Je réponds à Fabien LE LEZ qui dans
On Mon, 3 Oct 2005 08:32:00 +0200, "Patrick 'Zener' Brunet"
:

Certes, mais il y a une perte de performance dont il vaut
mieux être au courant


Yep. Ça permet d'optimiser ce que le profiler dit qu'il faut
optimiser...


Question de point de vue ;-)

Moi je préfère concevoir (efficace+robuste) d'emblée que
corriger ensuite pour rendre efficace en essayant de ne pas
casser la robustesse. Certes c'est plus complexe, mais ça
vaut le coup.


Ce qui veut dire, réalistiquement ?

Moi, je considère l'efficacité algorithmique au niveau de la
conception, éventuellement. (C-à-d que si je sais que j'ai des
millions d'éléments à traiter, j'évite des algorithmes
quadratiques.) Mais pour la reste, je fais du propre, sans trop
m'inquieter des performances. Et j'encapsule à mort. De façon à
ce que quand le profiler me dit qu'il y a un problème à un
endroit donné, je peux bien optimiser ce point sans
répercussions ailleurs.

J'ai vu des programmeurs qui essayaient à faire autrement. Qui
prenaient en compte les questions de performance des le début --
pas de std::string (ou son équivalent d'avant la norme), à cause
des allocations dynamiques, par exemple. Chose curieuse, leur
code était toujours moins rapide que le mien, quand il
importait.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Patrick 'Zener' Brunet
Bonjour.

Je réponds à kanze
Patrick 'Zener' Brunet wrote:

Je réponds à Fabien LE LEZ qui dans
On Mon, 3 Oct 2005 08:32:00 +0200, "Patrick 'Zener' Brunet"
:

Certes, mais il y a une perte de performance dont il vaut
mieux être au courant


Yep. Ça permet d'optimiser ce que le profiler dit qu'il faut
optimiser...


Question de point de vue ;-)

Moi je préfère concevoir (efficace+robuste) d'emblée que
corriger ensuite pour rendre efficace en essayant de ne pas
casser la robustesse. Certes c'est plus complexe, mais ça
vaut le coup.


Ce qui veut dire, réalistiquement ?



Par exemple, je me suis doté - un peu par défi, certes :-) - de classes
alternatives, comme par exemple une classe texte qui travaille sur un buffer
externe (simple tableau automatique).
Et donc lorsque je veux profiter des fonctionnalités "avancées" de cette
classe texte et que la taille prévue pour le texte le permet, préférer cette
classe supprime le travail d'allocation.

Dans le cas que je citais (A = B + C;), la classe dynamique fait intervenir
un "don de buffer" qui est donc embarqué dans ce composant et s'applique
automatiquement à ce scénario précis.

J'en ai d'autres...

* Par exemple utiliser des heaps "jetables" (sans libération de chaque unité
de mémoire) pour héberger des grappes d'objets qui doivent être débarrassés
globalement, ce qui arrive typiquement dans la compilation type IA (élagage
de branches d'analyse),

* Par exemple aussi utiliser des heaps dont les algorithmes d'allocation
sont adaptés aux cycles et formats des données hébergées (blocs fixes, buddy
blocks, first fit / best fit, ...)

Je sais bien que ça serait peut-être complexe à enseigner à des débutants et
donc que paradoxalement ça génèrerait un surcoût et des risques de bugs,
mais ma position actuelle est celle d'un chercheur. J'ai longtemps cru au
code pérenne et capitalisable, mais je suis en train de développer une autre
stratégie qui peut être plus avantageuse...


Moi, je considère l'efficacité algorithmique au niveau de la
conception, éventuellement. (C-à-d que si je sais que j'ai des
millions d'éléments à traiter, j'évite des algorithmes
quadratiques.) Mais pour la reste, je fais du propre, sans trop
m'inquieter des performances. Et j'encapsule à mort. De façon à
ce que quand le profiler me dit qu'il y a un problème à un
endroit donné, je peux bien optimiser ce point sans
répercussions ailleurs.



Je suis 100% d'accord sur le principe, mais ...
Je ne suis pas sûr que le profiler puisse forcément tout voir dans le
contexte IA-like où je travaille souvent et où les liens entre modules ne
sont pas forcément explicites (ie: ils sont souvent dynamiques et peuvent
être très optionnels).
Ils se prêtent donc mal à une analyse formelle, et dans le même temps la
validation par l'expérimentation n'est pas une preuve.
Ca m'ennuie beaucoup parce que certains algorithmes peuvent être
intéressants ou inutilisables selon un seuil de complexité, et alors
puisqu'il faut de toute manière prendre ce seuil en compte dès la
conception, je n'aime pas l'idée de le perdre de vue par moments.

J'ai travaillé longtemps dans le monde de l'IA traditionnelle, et si elle
est reconnue non crédible dans tout contexte industriel, c'est précisément à
cause de cet effet roulette russe: soit on mobilise la plus grosse machine
disponible et on croise les doigts, soit on joue avec les paramètres de la
mémoire jusqu'à ce que **l'instance de** calcul passe sans débordement.
C'est très bien pour une démo en université, mais au-delà ?

En C/C++ "standard" ce genre de chose n'arrive pas normalement, mais
finalement où se situe précisément la frontière du "standard" ?


J'ai vu des programmeurs qui essayaient à faire autrement. Qui
prenaient en compte les questions de performance des le début --
pas de std::string (ou son équivalent d'avant la norme), à cause
des allocations dynamiques, par exemple. Chose curieuse, leur
code était toujours moins rapide que le mien, quand il
importait.


C'est amusant comme en se concentrant sur un détail on peut perdre de vue
l'essentiel. J'ai vu aussi des horreurs, et pas seulement dans le code
informatique :-D

Mais je n'ai pas dit que c'était facile. Je suis même convaincu aujourd'hui
que ça dépassera de plus en plus en complexité les facultés du cerveau
humain non assisté. C'est même pour ça que je cherche une autre stratégie.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/




Avatar
kanze
Patrick 'Zener' Brunet wrote:

Je réponds à kanze
Patrick 'Zener' Brunet wrote:

Je réponds à Fabien LE LEZ qui dans
On Mon, 3 Oct 2005 08:32:00 +0200, "Patrick 'Zener' Brunet"
:

Certes, mais il y a une perte de performance dont il vaut
mieux être au courant


Yep. Ça permet d'optimiser ce que le profiler dit qu'il
faut optimiser...


Question de point de vue ;-)

Moi je préfère concevoir (efficace+robuste) d'emblée que
corriger ensuite pour rendre efficace en essayant de ne pas
casser la robustesse. Certes c'est plus complexe, mais ça
vaut le coup.


Ce qui veut dire, réalistiquement ?


Par exemple, je me suis doté - un peu par défi, certes :-) -
de classes alternatives, comme par exemple une classe texte
qui travaille sur un buffer externe (simple tableau
automatique). Et donc lorsque je veux profiter des
fonctionnalités "avancées" de cette classe texte et que la
taille prévue pour le texte le permet, préférer cette classe
supprime le travail d'allocation.

Dans le cas que je citais (A = B + C;), la classe dynamique
fait intervenir un "don de buffer" qui est donc embarqué dans
ce composant et s'applique automatiquement à ce scénario
précis.


Ce qui est une optimisation valide quand le profiler montre
qu'il le faut. C'est rarement le cas, au moins que ton
application ne fait que manipuler des chaînes (et encore).

J'en ai d'autres...

* Par exemple utiliser des heaps "jetables" (sans libération
de chaque unité de mémoire) pour héberger des grappes d'objets
qui doivent être débarrassés globalement, ce qui arrive
typiquement dans la compilation type IA (élagage de branches
d'analyse),


Encore, c'est une optimisation qui m'a déjà servi, quand le
profiler en a indiqué la nécessité. (Aujourd'hui, j'utilise un
glaneur de cellules la plupart du temps. Alors, c'est encore
plus simple -- un simple appel d'une seule fonction au moment
critique.)

* Par exemple aussi utiliser des heaps dont les algorithmes
d'allocation sont adaptés aux cycles et formats des données
hébergées (blocs fixes, buddy blocks, first fit / best fit,
...)


Mais c'est transparent. L'interface (et même l'implémentation)
des classes utilisateur n'y voit pas de différence.

Je sais bien que ça serait peut-être complexe à enseigner à
des débutants et donc que paradoxalement ça génèrerait un
surcoût et des risques de bugs, mais ma position actuelle est
celle d'un chercheur. J'ai longtemps cru au code pérenne et
capitalisable, mais je suis en train de développer une autre
stratégie qui peut être plus avantageuse...


Le problème, c'est que même si tu conçois le code avec l'idée de
le jeter, il risque de vivre plus que tu n'y attends.

Moi, je considère l'efficacité algorithmique au niveau de la
conception, éventuellement. (C-à-d que si je sais que j'ai
des millions d'éléments à traiter, j'évite des algorithmes
quadratiques.) Mais pour la reste, je fais du propre, sans
trop m'inquieter des performances. Et j'encapsule à mort. De
façon à ce que quand le profiler me dit qu'il y a un
problème à un endroit donné, je peux bien optimiser ce point
sans répercussions ailleurs.


Je suis 100% d'accord sur le principe, mais ...

Je ne suis pas sûr que le profiler puisse forcément tout voir
dans le contexte IA-like où je travaille souvent et où les
liens entre modules ne sont pas forcément explicites (ie: ils
sont souvent dynamiques et peuvent être très optionnels).


Le profiler marche lors de l'exécution. Il voit donc ce qui se
passe lors de l'exécution.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34





1 2