• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed pojemność pojemników STL multiset, list, ....

Object Storage Arubacloud
0 głosów
300 wizyt
pytanie zadane 15 lipca 2019 w C i C++ przez niezalogowany
zamknięte 13 listopada 2019
Czy tylko u mnie, czy u wszystkich jak kontener ma ponad 4000 elementów , to program kończy się błędem?
komentarz zamknięcia: najlepsza
1
komentarz 15 lipca 2019 przez adrian17 Ekspert (344,860 p.)
Tylko u Ciebie. Coś musisz robić źle.

Pokażesz proszę kod?
komentarz 15 lipca 2019 przez niezalogowany
#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;
}
//**************************************************************************

 

2 odpowiedzi

+1 głos
odpowiedź 15 lipca 2019 przez adrian17 Ekspert (344,860 p.)
wybrane 13 listopada 2019
 
Najlepsza
    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.

komentarz 15 lipca 2019 przez niezalogowany
Przepisywałem i się machnąłem ale to nie to. Powinno być rozmiar= 50 *4000; (50 const)
komentarz 15 lipca 2019 przez niezalogowany

działająca wersja, tylko nie poprawnie

#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=0;

    srand (time(0));
    const int rozmiar =50*2000;
    punkt table [rozmiar];
    ile = 50;
    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;
}

 

komentarz 15 lipca 2019 przez niezalogowany
edycja 15 lipca 2019
I takie drugie pytanie czy mymultiset.erase(myiter), czy to dobre rozwiązanie, i jaka jest tego złożoność obliczeniowa.

I trzecie pytanie  multiset <punkt,compare_x> lista_x(table,table+rozmiar-1); jest dużo wolniejsze niż, to co zrobiłem. Dlaczego?

4) Czy "napompowanie" kontenera zerami do określonego rozmiaru da i jakieś korzyści. I jeśli, to jakim konstruktorem.
komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)
edycja 15 lipca 2019 przez j23

Ad 3) Zgaduje, że równoważenie dużego drzewa* (100000 elementów) zajmuje więcej czasu niż równoważenie 50 mniejszych (2000 elementów).

Ad 4) nie, to nie std::vector.

 

*) przy założeniu, że kontener set to drzewo zrównoważone.

komentarz 15 lipca 2019 przez niezalogowany
Dzięki j23, za twoje cenne jak zawsze uwagi.

Ad 3) nie pomyślałem, że to tak wygląda.

Mam jeszcze jedno bardzo ważne pytanie. Kontenery są wygodne, ale dużo wolniejsze od stałych tablic i wskaźników. Tak?
komentarz 15 lipca 2019 przez tkz Nałogowiec (42,000 p.)

@j23, Ad 4) nie, to nie std::vector.

Dlaczego, to by miało coś zmienić?

komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)

@fisker, nie są dużo wolniejsze od tablic.... zresztą porównywanie mapy czy seta ze zwykłą tablicą jest nieporozumieniem. Kontener std::vector czy std::array większości przypadków jest równie szybki (o ile nie szybszy) jak tradycyjne tablice. Trzeba tylko wiedzieć, co się robi.

@tkz, nie rozumiem. Gdzie napisałem, że to coś zmienia?

 

komentarz 15 lipca 2019 przez niezalogowany
ok dzięki.
komentarz 15 lipca 2019 przez tkz Nałogowiec (42,000 p.)

@j23,

 

4) Czy "napompowanie" kontenera zerami do określonego rozmiaru da i jakieś korzyści. I jeśli, to jakim konstruktorem.

Ad 4) nie, to nie std::vector.

Chyba, że miałeś na myśli konstruktor...

komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)
Miałem na myśli rezerwowanie miejsca na przyszłe elementy.
komentarz 15 lipca 2019 przez tkz Nałogowiec (42,000 p.)
Właśnie o to chciałem zapytać. Czy taka rezerwacja coś zmienia?
komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)

Zmienia, bo możesz zredukować (czasami) do zera ilość realokacji pamięci w trakcie dodawania nowych elementów (vide std::vector::reserve).

komentarz 15 lipca 2019 przez niezalogowany
edycja 15 lipca 2019

  Jednak nie to samo. Nie wiem czy to jest miarodajny przykład. Ale wektor jest 2 razy wolniejszy pewnie ma to związek właśnie z relokacją pamięci, lub nie? Ja tego nie wiem.

clock_t start1 = clock();
    for (int i =0; i<rozmiar; i++ )
    //    table[i]=losuj();
     //   sort (table,table+rozmiar-1,compare_x());
    v1.push_back(losuj());
   sort(v1.begin(),v1.end(),compare_x());
    cout<< "Czas wykonywania tab: "<<( clock() - start1 );

tab =0.1s

v1=0.2s

edit :

Ale to już podobnie:
v1.resize(rozmiar);
v1.at(i)=losuj();

komentarz 15 lipca 2019 przez tkz Nałogowiec (42,000 p.)

@j23, Dzięki. 

komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)

@fisker,   daj v1.reserve(rozmiar); przed pętlą.

komentarz 15 lipca 2019 przez niezalogowany
edycja 15 lipca 2019
resize() dałem przed pętlą.

ale reverse no nie wiem

Czas wykonywania tab: 20terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)

ale to już hula pięknie

 v1.resize(rozmiar/2);
  v1.reserve(rozmiar);

Czas wykonywania tab: 0.85

edit :: znaczy się hulało prze chwilą

edit: znaczy się to v1[i]=losuj(); ,ale chyba wychodzę poza obszar vectora, bo v1.at(i)=losuj(); wyrzuca błąd, a przecież jest bezpieczniejsze.
komentarz 15 lipca 2019 przez j23 Mędrzec (194,920 p.)

W przypadku reserve musisz użyć push_back.

komentarz 15 lipca 2019 przez mokrowski Mędrzec (155,460 p.)

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 :)

komentarz 15 lipca 2019 przez niezalogowany
no cóż "traktowanie kompilatora" jako świadomego pracownika to jeszcze, daleka droga przede mną. Ale zrozumienie podstawowych tematów staje się łatwiejsze to to fajne uczucie.
komentarz 16 lipca 2019 przez j23 Mędrzec (194,920 p.)

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".

komentarz 16 lipca 2019 przez mokrowski Mędrzec (155,460 p.)
edycja 16 lipca 2019 przez mokrowski

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

0 głosów
odpowiedź 15 lipca 2019 przez manjaro Nałogowiec (37,390 p.)

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);
    }
}

 

komentarz 15 lipca 2019 przez niezalogowany
to ok.

Podobne pytania

0 głosów
1 odpowiedź 118 wizyt
pytanie zadane 1 kwietnia 2017 w C i C++ przez krzakurts Obywatel (1,470 p.)
0 głosów
1 odpowiedź 103 wizyt
pytanie zadane 12 sierpnia 2019 w C i C++ przez niezalogowany
0 głosów
2 odpowiedzi 416 wizyt
pytanie zadane 8 lipca 2019 w C i C++ przez niezalogowany

92,579 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,964 pasjonatów

Motyw:

Akcja Pajacyk

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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...