#include <iostream> #include <set> #include <algorithm> #include <ctime> struct punkt { int x; int y; int num=0; } temp; struct compare_x { inline bool operator() (const punkt& struct1, const punkt& struct2) { return (struct1.x ==struct2.x)? (struct1.y <struct2.y): (struct1.x <struct2.x); } }; struct tripoint { int a=0; int b=0; int c=0; } abc; punkt losuj () { int a=rand()%20000-10000; int b=rand()%20000-10000; return {a,b,0}; } //************************************************************************ using namespace std; //*********************************************************************** int main() { short ile=0; int iletr=50; srand (time(0)); const int rozmiar =ile*4000; punkt table [rozmiar]; iletr = rozmiar/ile; clock_t start1 = clock(); for (int i =0; i<rozmiar; i++ ) table[i]=losuj(); cout<< "Czas wykonywania tab: "<<( clock() - start1 ); clock_t start = clock(); while (ile--) { multiset <punkt,compare_x> lista_x{}; for (int i=0; i<iletr/*&&cin>>temp.x>>temp.y*/; ) { temp = table [i]; temp.num=++i; lista_x.insert (temp); } } cout<< "Czas wykonywania: "<<( clock() - start ); return 0; } //**************************************************************************
short ile=0; int iletr=50; srand (time(0)); const int rozmiar =ile*4000; punkt table [rozmiar]; iletr = rozmiar/ile;
Um... robisz tu tablicę o rozmiarze 4000*0, po czym w dodatku dzielisz przez 0.
W przypadku reserve musisz użyć push_back.
Po reserve(), raczej emplace_back(...) bo alokacja "in place".
@fidker, co do optymalizacji, dodaj przełączniki optymalizacji i dopiero sprawdź wydajność każdego z rozwiązań. Będziesz często zdumiony. Im więcej kompilator wie co zastosowaniu kodu, tym bardziej może go optymalizować. Traktuj go jak świadomego pracownika który zna się na swojej pracy a nie stażystę któremu masz podtykać pod nos rozwiązania i jeszcze "kołczować" co robi źle :)
raczej emplace_back(...) bo alokacja "in place".
W tym przypadku to raczej bez znaczenia, bo i tak zostanie wywołany (przynajmniej w teorii) ctor "przenoszący".
W emplace_back(...) przekazujesz argumenty konstruktora obiektu który będzie alokowany w pamięci już zarezerwowanej.
W przypadku push_back(..), powinieneś zapewnić obiektowi semantykę przenoszenia lub kopiowania. A to czy będzie lub nie powinna być wywołana, trochę zmieniało się ze standardami.
Taki kawałek prostego kodu pokazuje co i kiedy się dzieje:
#include <vector> #include <iostream> struct X { explicit X(int data_) : data{data_} { std::cout << "CONSTRUCT!!\n"; } X(const X& x) { std::cout << "COPY!!\n"; data = x.data; } X& operator=(const X& x) { std::cout << "ASSIGN!!\n"; if(&x != this) { data = x.data; } return *this; } int getData() const { return data; } private: int data; }; int main() { constexpr static std::size_t element_num = 80; std::vector<X> vec; //vec.reserve(element_num); for(int i = 0; i < element_num; ++i) { //vec.emplace_back(i); vec.push_back(X(i)); } }
W zależności od odkomentowanych linii z reserve(..) i push_back(), ilość operacji naiwnie mierzona w ten sposób:
./program | wc -l
W moim systemie wynosi (w innych systemach wyniki mogą być inne ale porównania wypadną podobnie):
1. Brak reserve() i zwykły push_back() : 287
2. Jest reserve() i zwykły push_back() : 160
3. Brak reserve() i jest emplace_back(): 207
4. Jest reserve() i jest emplace_back(): 80
Sprawdź czy to Ci się skompiluje.
Jeżeli tak to widocznie coś w swoich programach robisz źle.
#include <iostream> #include <list> int main(){ std::list<int> lista; for (int i=1;i<1000000;i++) { lista.push_back(i); } }
93,741 zapytań
142,676 odpowiedzi
323,294 komentarzy
63,319 pasjonatów
Motyw:
Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡
Oto polecana książka warta uwagi.Pełną listę książek znajdziesz tutaj
Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.