OVH Cloud OVH Cloud

allocation/desallocation dans le tas au sein d'un même bloc

12 réponses
Avatar
Olivier Azeau
Dans un thread récent, il a été mentionné à juste titre qu'on ne doit
jamais écrire :
{
A *a = new A;
delete a;
}
mais :
{
A a;
}

Cependant, il y a un cas où on l'écrit sans pouvoir y faire grand chose.
Quand la classe A est une interface publique qui implémente une
technique d'isolement pour éviter les problèmes de compatibilité binaire :

class ImplA
{
int x;
double y;
...
}

class A
{
ImplA *impl;
public:
A() { impl = new ImplA; }
~A() { delete impl; }
};

Existe-t-il des techniques qui permettent de minimiser l'impact des
allocations dans le tas pour un tel cas ?

2 réponses

1 2
Avatar
kanze
Gabriel Dos Reis wrote:
Fabien LE LEZ writes:

| On Mon, 13 Dec 2004 21:57:06 +0100, "Arnaud Debaene"
| :

| >Ceci-dit, je ne sais pas ce qu'Olivier avait en tête quand il
| >parlait de "l'impact" des allocations dynamiques

| Le seul problème que je vois, c'est que l'allocation dynamique est
| gourmande en temps. Ceci dit, il reste à prouver que l'impact en
| question est mesurable...

Mais en C++, on peut toujours redéfinir sa propre fonction
d'allocation. Ceci dit, j'ai toujours trouvé le glaneur de cellule
natif de C assez efficace.


Ça dépend de l'implémentation et de l'application. Je me rappelle
bien
d'avoir écrit des operator new/delete spécifiques à une classe
plusieurs
fois, parce que le profiler m'a dit qu'il fallait. Plusieurs fois, pour
une accelération de plusieurs ordres de grandeurs.

Mais pas récemment. Alors, je ne sais pas si c'est parce que mes
applications ont changées, ou parce que les implémentations ont
améliorées, ou simplement parce que les machines sont devenues
tellement
plus rapides que ça n'a plus beaucoup d'importance. (Dans la mésure

l'application est assez rapide, je ne sors pas le profiler, et dans la
mésure que je ne sors pas le profileur, je n'ai aucune idée du coût
de
l'allocation.)

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Olivier Azeau
Gabriel Dos Reis wrote:
Olivier Azeau writes:
|
| Mais je me suis mal exprimé au départ. Je ne me place pas en fait dans
| un contexte où j'ai une grande latitude sur la classe A (pour diverses
| raisons, la principale étant que, dans bien des cas, elle provient
| d'un tiers)
| Ce que je me demande c'est comment faire a posteriori : j'ai une
| classe A dont l'instanciation "coute" et je veux pouvoir, sans trop me
| prendre la tête, l'utiliser comme une classe dont l'instanciation
| coute beaucoup moins.
| Ma 1ère idée c'est de wrapper la classe par une classe PooledA dont
| l'instanciation tire parti d'un ensemble réutilisable d'instances de A.

C'est ce que je disais dans mon précédent message. Tu peux rédéfinir
la fonction d'allocation « operator new » pour utiliser ta « pool ».
Elle peut être aussi rapide que l'incrémentation d'un pointeur.

| Le problème c'est que ça devient vite un enfer si on veut dériver A,
| si on veut prendre en compte que certaines méthodes ne supportent pas
| la réutilisation d'instance, ...

Là je ne te suis plus...



Non en fait je pensais à un cas où j'ai besoin de dériver mon A tiers en
une classe B, et que, non content de me taper le wrapping de A en
PooledA, je doive aussi me taper celui de B en PooledB (dont j'ai besoin
pour gérer séparément les instances de B de celles de A).

Mais, à la réflexion, en faisant dériver PooledB de PooledA, tout
devrait bien se passer : il ne semble pas y avoir de raisons pour qu'un
operator A& au niveau de PooledA ne fonctionne pas correctement pour un
PooledB.

1 2