Is het efficiënter om een ​​vector te kopiëren door te reserveren en te kopiëren, of door te maken en te ruilen? [DUPLICEER]

Ik probeer efficiënt een kopie van een vector te maken. Ik zie twee mogelijke benaderingen:

std::vector<int> copyVecFast1(const std::vector<int>& original)
{
  std::vector<int> newVec;
  newVec.reserve(original.size());
  std::copy(original.begin(), original.end(), std::back_inserter(newVec));
  return newVec;
}
std::vector<int> copyVecFast2(std::vector<int>& original)
{
  std::vector<int> newVec;
  newVec.swap(original);
  return newVec;
}

Welke van deze heeft de voorkeur en waarom? Ik ben op zoek naar de meest efficiënte oplossing die onnodig kopiëren vermijdt.


Antwoord 1, Autoriteit 100%

Uw tweede voorbeeld werkt niet als u het argument per referentie verzendt. Bedoelde u

void copyVecFast(vec<int> original) // no reference
{
  vector<int> new_;
  new_.swap(original); 
}

Dat zou werken, maar een gemakkelijkere manier is

vector<int> new_(original);

Antwoord 2, Autoriteit 200%

Ze zijn echter niet hetzelfde, toch? één is een kopie, de andere is een swap . Vandaar de functienamen.

Mijn favoriet is:

a = b;

Waar aen bzijn vectoren.


Antwoord 3, Autoriteit 59%

Dit is een andere geldige manier om een ​​kopie van een vector te maken, gebruik gewoon de constructor:

std::vector<int> newvector(oldvector);

Dit is nog eenvoudiger dan het gebruik van std::copyom de hele vector van begin tot eind naar std::back_insertte lopen in de nieuwe vector.

>

Dat gezegd hebbende, je .swap()is geen kopie, maar verwisselt de twee vectoren. Je zou het origineel wijzigen om niets meer te bevatten! Wat geen kopie is.


Antwoord 4, autoriteit 20%

Direct antwoord:

  • Gebruik een =operator

We kunnen de openbare lidfunctie std::vector::operator=van de container std::vectorgebruiken om waarden van een vector aan een andere toe te wijzen.

  • Gebruik een constructorfunctie

Bovendien is een constructorfunctie ook zinvol. Een constructorfunctie met een andere vector als parameter (bijv. x) construeert een container met een kopie van elk van de elementen in x, in dezelfde volgorde.

Let op:

  • Gebruik std::vector::swap
  • . niet

std::vector::swapis niet kopiëreneen vector naar een andere, het verwisselt eigenlijk elementen van twee vectoren, net zoals de naam doet vermoeden. Met andere woorden, de bronvector waaruit moet worden gekopieerd, wordt gewijzigd nadat std::vector::swapis aangeroepen, wat waarschijnlijk niet is wat u verwacht.

  • Diepe of oppervlakkige kopie?

Als de elementen in de bronvector verwijzingen zijn naar andere gegevens, dan is soms een diepe kopie gewenst.

Volgens wikipedia:

Een diepe kopie, wat betekent dat de referenties van velden worden verwijderd: in plaats van verwijzingen naar objecten die worden gekopieerd, worden nieuwe kopieerobjecten gemaakt voor alle objecten waarnaar wordt verwezen, en verwijzingen ernaar worden in B geplaatst.

Eigenlijk is er momenteel geen ingebouwde manier in C++ om een diepe kopie te maken. Alle hierboven genoemde manieren zijn oppervlakkig. Als een diepe kopie nodig is, kunt u een vector doorkruisen en de referenties handmatig kopiëren. Als alternatief kan een iterator worden overwogen voor het doorlopen. Discussie over iterator gaat verder dan deze vraag.

Referenties

De pagina van std::vectorop cplusplus.com


Antwoord 5, autoriteit 12%

new_vector.assign(old_vector.begin(),old_vector.end()); // Method 1
new_vector = old_vector; // Method 2

Antwoord 6, autoriteit 11%

u moet swap niet gebruiken om vectoren te kopiëren, dit zou de “originele” vector veranderen.

geef in plaats daarvan het origineel als parameter door aan het nieuwe.

Other episodes