std::string de VC++ utilise un buffer interne de 16
octets pour stocker les petites chaines (sur la pile donc) et fait un new
si
c'est pas suffisant
Ca doit être leur réponse à la suppression du COW.
Je croyais que c'était déjà le cas avant ?
std::string de VC++ utilise un buffer interne de 16
octets pour stocker les petites chaines (sur la pile donc) et fait un new
si
c'est pas suffisant
Ca doit être leur réponse à la suppression du COW.
Je croyais que c'était déjà le cas avant ?
std::string de VC++ utilise un buffer interne de 16
octets pour stocker les petites chaines (sur la pile donc) et fait un new
si
c'est pas suffisant
Ca doit être leur réponse à la suppression du COW.
Je croyais que c'était déjà le cas avant ?
N'y a-t-il pas un risque à utiliser cette technique
(passage par
référence d'un objet temporaire, ...) ?
Si on ne modifie pas l'objet, pourquoi le garder ?
Dans quels cas, peut-on l'utiliser ?
N'y a-t-il pas un risque à utiliser cette technique
(passage par
référence d'un objet temporaire, ...) ?
Si on ne modifie pas l'objet, pourquoi le garder ?
Dans quels cas, peut-on l'utiliser ?
N'y a-t-il pas un risque à utiliser cette technique
(passage par
référence d'un objet temporaire, ...) ?
Si on ne modifie pas l'objet, pourquoi le garder ?
Dans quels cas, peut-on l'utiliser ?
Si on ne modifie pas l'objet, pourquoi le garder ?
std::string f()
{
std::string x;
return x;
}
void g()
{
std::string y= f();
}
Ici, il y a une copie, très difficile à éviter à moins de changer
complètement l'écriture :
void f (std::string& dest)
{
std::string x;
dest= x;
}
void g()
{
std::string y;
f(y);
}
Si on ne modifie pas l'objet, pourquoi le garder ?
std::string f()
{
std::string x;
return x;
}
void g()
{
std::string y= f();
}
Ici, il y a une copie, très difficile à éviter à moins de changer
complètement l'écriture :
void f (std::string& dest)
{
std::string x;
dest= x;
}
void g()
{
std::string y;
f(y);
}
Si on ne modifie pas l'objet, pourquoi le garder ?
std::string f()
{
std::string x;
return x;
}
void g()
{
std::string y= f();
}
Ici, il y a une copie, très difficile à éviter à moins de changer
complètement l'écriture :
void f (std::string& dest)
{
std::string x;
dest= x;
}
void g()
{
std::string y;
f(y);
}
On Wed, 23 Feb 2005 18:38:27 +0100, dezz :N'y a-t-il pas un risque à utiliser cette technique
Si, beaucoup.
C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,
si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),
alors tu peux commencer à envisager d'implémenter COW.
On Wed, 23 Feb 2005 18:38:27 +0100, dezz <dezz@dezz.net>:
N'y a-t-il pas un risque à utiliser cette technique
Si, beaucoup.
C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,
si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),
alors tu peux commencer à envisager d'implémenter COW.
On Wed, 23 Feb 2005 18:38:27 +0100, dezz :N'y a-t-il pas un risque à utiliser cette technique
Si, beaucoup.
C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,
si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),
alors tu peux commencer à envisager d'implémenter COW.
Fabien LE LEZ wrote:On Wed, 23 Feb 2005 18:38:27 +0100, dezz :N'y a-t-il pas un risque à utiliser cette techniqueSi, beaucoup.
Pas vraiment, si on sait ce qu'on fait, et que l'interface est
conçue pour le supporter.C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
La raison pourquoi on l'abandonne pour std::string, c'est que
l'interface de std::string est mal conçue. En général, mais
surtout, elle est mal conçue pour cette technique.
[...]A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Ce n'est pas si simple que ça, bien que tu as raison en
principe.Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
AMHA, c'est en général préférable à limiter la complexité à une
seule classe. Je préfère implémenter COW dans une classe, bien
localiser, que de me forcer de me servir des pointeurs partout,
quand la logique du programme ne l'exige pas.si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),alors tu peux commencer à envisager d'implémenter COW.
Il existe de bons algorithmes « lock-free » pour le
multi-thread, à condition, évidemment, que l'interface permet à
s'en servir. Et même avec un lock -- prendre un lock est souvent
moins cher qu'une copie profonde, surtout s'il faut des
allocations pour faire la copie profond. (Il est probable que
l'allocateur prend un lock.)
--
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
Fabien LE LEZ wrote:
On Wed, 23 Feb 2005 18:38:27 +0100, dezz <dezz@dezz.net>:
N'y a-t-il pas un risque à utiliser cette technique
Si, beaucoup.
Pas vraiment, si on sait ce qu'on fait, et que l'interface est
conçue pour le supporter.
C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
La raison pourquoi on l'abandonne pour std::string, c'est que
l'interface de std::string est mal conçue. En général, mais
surtout, elle est mal conçue pour cette technique.
[...]
A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Ce n'est pas si simple que ça, bien que tu as raison en
principe.
Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,
si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
AMHA, c'est en général préférable à limiter la complexité à une
seule classe. Je préfère implémenter COW dans une classe, bien
localiser, que de me forcer de me servir des pointeurs partout,
quand la logique du programme ne l'exige pas.
si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),
alors tu peux commencer à envisager d'implémenter COW.
Il existe de bons algorithmes « lock-free » pour le
multi-thread, à condition, évidemment, que l'interface permet à
s'en servir. Et même avec un lock -- prendre un lock est souvent
moins cher qu'une copie profonde, surtout s'il faut des
allocations pour faire la copie profond. (Il est probable que
l'allocateur prend un lock.)
--
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
Fabien LE LEZ wrote:On Wed, 23 Feb 2005 18:38:27 +0100, dezz :N'y a-t-il pas un risque à utiliser cette techniqueSi, beaucoup.
Pas vraiment, si on sait ce qu'on fait, et que l'interface est
conçue pour le supporter.C'est pour ça que c'est compliqué à mettre en oeuvre (surtout
en programmation multithread), et que la technique est de plus
en plus abandonnée, pour std::string du moins.
La raison pourquoi on l'abandonne pour std::string, c'est que
l'interface de std::string est mal conçue. En général, mais
surtout, elle est mal conçue pour cette technique.
[...]A priori, tu ne dois pas mettre en place un tel système dans
les classes que tu crées.
Ce n'est pas si simple que ça, bien que tu as raison en
principe.Si le profiler indique que les copies d'objets de classe C
prennent vraiment trop de temps et ralentissent sensiblement
le programme,si tu ne peux vraiment pas éviter les copies en questions
(il y a beaucoup de façons d'éviter des copies -- par exemple,
utiliser des pointeurs),
AMHA, c'est en général préférable à limiter la complexité à une
seule classe. Je préfère implémenter COW dans une classe, bien
localiser, que de me forcer de me servir des pointeurs partout,
quand la logique du programme ne l'exige pas.si tu es sûr que ta classe ne sera jamais utilisée en
multithread (c'est de plus en plus rare),alors tu peux commencer à envisager d'implémenter COW.
Il existe de bons algorithmes « lock-free » pour le
multi-thread, à condition, évidemment, que l'interface permet à
s'en servir. Et même avec un lock -- prendre un lock est souvent
moins cher qu'une copie profonde, surtout s'il faut des
allocations pour faire la copie profond. (Il est probable que
l'allocateur prend un lock.)
--
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
Si je comprends bien le principe, on peut arriver à qqc comme
ça si le cout d'une copie est trop important :
class A {
A& operator=(const A& a1) {
if (_tmpAssign != NULL)
{
_tmpAssign->Release();
_tmpAssign = NULL;
}
_tmpAssign = &a1;
a1.addReference();
}
private:
void addReference() {
_count++;
}
void Release() {
count--;
if (count == 0} {
delete this;
}
}
A* _tmpAssig;
int count;
}
Mon raisonnement est correct ?
Si je comprends bien le principe, on peut arriver à qqc comme
ça si le cout d'une copie est trop important :
class A {
A& operator=(const A& a1) {
if (_tmpAssign != NULL)
{
_tmpAssign->Release();
_tmpAssign = NULL;
}
_tmpAssign = &a1;
a1.addReference();
}
private:
void addReference() {
_count++;
}
void Release() {
count--;
if (count == 0} {
delete this;
}
}
A* _tmpAssig;
int count;
}
Mon raisonnement est correct ?
Si je comprends bien le principe, on peut arriver à qqc comme
ça si le cout d'une copie est trop important :
class A {
A& operator=(const A& a1) {
if (_tmpAssign != NULL)
{
_tmpAssign->Release();
_tmpAssign = NULL;
}
_tmpAssign = &a1;
a1.addReference();
}
private:
void addReference() {
_count++;
}
void Release() {
count--;
if (count == 0} {
delete this;
}
}
A* _tmpAssig;
int count;
}
Mon raisonnement est correct ?
Sauf que c'est toujours l'implémentation, et que
l'implémentation, qu'on gère par cette technique. Tout son
intérêt, c'est que l'utilisateur ne voit rien.
Dans un environement multi-thread, il est possible de le
modifier de façon à ce qu'il n'utilise que des primitifs du
genre atomicAdd et atomicSub, ou atomicIncr et atomicDecr, voire
même CAS directement.
Sauf que c'est toujours l'implémentation, et que
l'implémentation, qu'on gère par cette technique. Tout son
intérêt, c'est que l'utilisateur ne voit rien.
Dans un environement multi-thread, il est possible de le
modifier de façon à ce qu'il n'utilise que des primitifs du
genre atomicAdd et atomicSub, ou atomicIncr et atomicDecr, voire
même CAS directement.
Sauf que c'est toujours l'implémentation, et que
l'implémentation, qu'on gère par cette technique. Tout son
intérêt, c'est que l'utilisateur ne voit rien.
Dans un environement multi-thread, il est possible de le
modifier de façon à ce qu'il n'utilise que des primitifs du
genre atomicAdd et atomicSub, ou atomicIncr et atomicDecr, voire
même CAS directement.