Discussione:
STL library: copia e spostamento
(troppo vecchio per rispondere)
_merlinO_
2019-10-07 12:47:49 UTC
Permalink
Come ho scritto nel post poco più sotto sto facendo uno studio sulle collezioni della STL library. Tutto è partito dall'esigenza di spostare oggetti tra liste diverse (delle stesso tipo), avendo sempre e comunque un'istanza unica e univoca dell'elemento (niente copie e duplicati).

Per esempio: Abbiamo una classe Foo che contiene all'interno una semplice stringa "messaggio". I costruttori e operatori per copia e spostamento sono tutti implementati. Che differenze vi aspettate tra questo codice:

typedef std::list<Foo> foo_list;

foo_list collection1 = {
std::move(Foo{"Hello"}),
std::move(Foo{"collections"}),
std::move(Foo{"!!"})
};

foo_list collection2 = std::move(collection1);


e questo?

typedef std::list<std::shared_ptr<Foo>> foo_list;

foo_list collection1 = {
std::make_shared<Foo>("Hello"),
std::make_shared<Foo>("collections"),
std::make_shared<Foo>("!!"),
};

foo_list collection2 = std::move(collection1);
enoquick
2019-10-13 17:44:00 UTC
Permalink
Post by _merlinO_
Come ho scritto nel post poco più sotto sto facendo uno studio sulle collezioni della STL library. Tutto è partito dall'esigenza di spostare oggetti tra liste diverse (delle stesso tipo), avendo sempre e comunque un'istanza unica e univoca dell'elemento (niente copie e duplicati).
typedef std::list<Foo> foo_list;
foo_list collection1 = {
std::move(Foo{"Hello"}),
std::move(Foo{"collections"}),
std::move(Foo{"!!"})
};
foo_list collection2 = std::move(collection1);
e questo?
typedef std::list<std::shared_ptr<Foo>> foo_list;
foo_list collection1 = {
std::make_shared<Foo>("Hello"),
std::make_shared<Foo>("collections"),
std::make_shared<Foo>("!!"),
};
foo_list collection2 = std::move(collection1);
che il caso 2 sia piu performante di 1 dipende da Foo(Foo&&); come e'
fatto (quanta roba sposta e come la sposta)
Occorre anche tenere conto che shared_ptr va su heap,generalmente piu
lento come costruzione rispetto allo stack e comunque piu lento di
unique_ptr
Forse per una lista condivisa,se e' quello che si vuole ottenere (ma
dipende dal problema), non e' meglio un shared_ptr<foo_list>
senza stare a creare singoli elementi shared_ptr ?
--
|___|
_merlinO_
2019-10-17 10:00:36 UTC
Permalink
Post by enoquick
che il caso 2 sia piu performante di 1 dipende da Foo(Foo&&); come e'
fatto (quanta roba sposta e come la sposta)
Occorre anche tenere conto che shared_ptr va su heap,generalmente piu
lento come costruzione rispetto allo stack e comunque piu lento di
unique_ptr
Forse per una lista condivisa,se e' quello che si vuole ottenere (ma
dipende dal problema), non e' meglio un shared_ptr<foo_list>
senza stare a creare singoli elementi shared_ptr ?
L'esempio sposta tutta la lista, ma nel mio caso reale dovevo muovere solo determinati elementi che rispondono a una condizione.
Comunque la differenza è impressionante:
http://cpp.sh/2ch2v

*** No pointers (Primo esempio) ***
Constructor Foo() called for "Hello"
Move constructor Foo(Foo&& other) called for "Hello"
Constructor Foo() called for "collections"
Move constructor Foo(Foo&& other) called for "collections"
Constructor Foo() called for "!!"
Move constructor Foo(Foo&& other) called for "!!"
Assignment operator Foo& operator=(const Foo& other) called for "Hello"
Copy constructor Foo(const Foo& other) called for "Hello"
Assignment operator Foo& operator=(const Foo& other) called for "collections"
Copy constructor Foo(const Foo& other) called for "collections"
Assignment operator Foo& operator=(const Foo& other) called for "!!"
Copy constructor Foo(const Foo& other) called for "!!"
Destructor ~Foo() called for "!!"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "???moved???"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "!!"

*** With pointers (Secondo esempio) ***
Constructor Foo() called for "Hello"
Constructor Foo() called for "collections"
Constructor Foo() called for "!!"
Destructor ~Foo() called for "Hello"
Destructor ~Foo() called for "collections"
Destructor ~Foo() called for "!!"

Continua a leggere su narkive:
Loading...