funktion , quadratisches mittel



  • @5cript danke dir



  • @5cript Aber warum nicht einfach push_back? Gerade bei Zahlen ist es doch sehr einfach die Eingabe zu terminieren. Außerdem, braucht man wirklich einen vector? Klar, Trennung von I/O und Verarbeitung... Aber eigentlich kannst doch direkt die Summe bilden beim Einlesen, bei so einem kleinen Programm.



  • Dieser Beitrag wurde gelöscht!


  • @HarteWare Grundsätzlich: Wenn man die größe des vectors von anfang an kennt, dann in der größe erstellen oder resizen. Es tut nicht weh das immer zu machen.
    (EDIT: Zu allgemein formuliert, korrektur weiter unten)

    Denn push_back bedeutet potentiell mehrere Vergrößerungen, sprich reallokationen.

    Aber eigentlich kannst doch direkt die Summe bilden beim Einlesen, bei so einem kleinen Programm.

    Für das Beispiel? Ja kann man.
    Aber:

    • Ich hab mir 2 Minuten genommen hierfür
    • Ich wollte seine struktur erhalten, damit er im Vergleich den Unterschied sehen kann.


  • @5cript sagte in funktion , quadratisches mittel:

    @HarteWare Grundsätzlich: Wenn man die größe des vectors von anfang an kennt, dann in der größe erstellen oder resizen. Es tut nicht weh das immer zu machen.
    Denn push_back bedeutet potentiell mehrere Vergrößerungen, sprich reallokationen.

    Als allgemeiner Rat ist das denke ich schlecht. push_back ist schön doof und einfach, da kann man wenig falsch machen. Vorher Grösse ausrechnen und dann reinschreiben ist potentiell fehleranfällig, da man die Grösse dann an zwei Stellen im Code dupliziert hat. Und wenn die nicht zusammenstimmen ist aua. Wenn schon würde ich eher reserve + push_back empfehlen. Aber halt auch nur wenn es sich auszahlt an der Stelle überhaupt etwas zu optimieren.



  • @5cript sagte in funktion , quadratisches mittel:

    Denn push_back bedeutet potentiell mehrere Vergrößerungen, sprich reallokationen.

    Es existiert ja auch noch reserve, so dass man bei push_back mit deutlich weniger Allokationen auskommen kann.



  • reserve + push_back

    Ja kann man auch machen.
    Aber ich nutze reserve immer dann wenn ich genau NICHT weiß wie viel es wird, aber ich es erahnen kann.
    Also zum Beispiel um die 10k elemente, also reservier ich ~11k.

    Beispiel: Messdaten aufnehmen.

    Aber "ist weniger fehleranfällig" ist für mich schon fast leicht paranoid. "Könnte ja potentiell segfaulten". Diese Herangehensweise teil ich nicht.
    EDIT: Vorausgesetzt man alloziiert nicht an einer Stelle und befüllt an einer anderen zu anderer Zeit. Ich meinte explizit: Wenn man GANZ GENAU an DER STELLE weiß wie groß der vector wird und er direkt dort befüllt wird.
    Aber das ist hier wieder ein Punkt den ich nicht verteidigen muss. Wenn jemand lieber mit reserve arbeitet, dann ist das für mich völlig ok und würde ich nicht kritisieren.

    Man kann reserve auch einfach in existierenden code klatschen im gegensatz zu nem resize. Und potentiell Performance gewinnen



  • @5cript sagte in funktion , quadratisches mittel:

    Ich meinte explizit: Wenn man GANZ GENAU an DER STELLE weiß wie groß der vector wird und er direkt dort befüllt wird.

    Sowas ist OK (nur mMn. sinnlos):

    static const size_t N = 123;
    vec.resize(N);
    for (size_t i = 0; i < N; i++)
        vec[i] = ...;
    

    U.u. fragwürdig aber vermutlich OK:

    vec2.resize(KONSTANTE_DIE_WO_ANDERS_DEFINIERT_IST);
    for (size_t i = 0; i < KONSTANTE_DIE_WO_ANDERS_DEFINIERT_IST; i++)
        vec2[i] = ...;
    

    Sowas nicht:

    vec.resize(8);
    vec[0] = ...;
    vec[1] = ...;
    vec[2] = ...;
    vec[3] = ...;
    vec[4] = ...;
    vec[5] = ...;
    vec[6] = ...;
    vec[7] = ...;
    
    vec2.resize(123);
    for (size_t i = 0; i < 123; i++)
        vec2[i] = ...;
    

    Mache ich aber normalerweise alles wie gesagt nicht. Weil ich es für einen sinnlose Optimierung halte die vermutlich nichtmal immer eine ist.

    Kleine konstante Anzahl = initializer_list
    Spezialfall genaue oder ungefähre Anzahl bekannt und die Stelle sollte optimiert werden = reserve + push_back bzw. reserve + emplace_back
    Ansonsten = Einfach push_back/emplace_back



  • @hustbaer

    ich verstehe deinen Standpunkt nicht.
    Folgendes kommt sogar oft vor:

    std::vector <T> v(n);
    // std::copy from to
    // std::fill
    // for from to (<- das gleiche nur zu fuß)
    // ...
    

    Defensives Programmieren sehe ich viel gefährlicher. Beim Programmieren "Angst" zu haben ist keine gute Einstellung.
    Was ist so schlimm daran ein vector der korreten größe zu erzeugen und direkt zu initialisieren?



  • @5cript sagte in funktion , quadratisches mittel:

    Folgendes kommt sogar oft vor:
    std::vector <T> v(n);

    Moeglicherweise brauchst du dort keinen vector, sondern ein auto v = std::make_unique<T[]>(n) wäre ausreichend.



  • @wob sagte in funktion , quadratisches mittel:

    @5cript sagte in funktion , quadratisches mittel:

    Folgendes kommt sogar oft vor:
    std::vector <T> v(n);

    Moeglicherweise brauchst du dort keinen vector, sondern ein auto v = std::make_unique<T[]>(n) wäre ausreichend.

    ?
    Und was ist bitte der Vorteil davon?
    Man verliert doch dann das komplette interface.
    .size(), ...

    Was für ein merkwürdiger Vorschlag???
    Ich verstehe dieses Forum einfach nicht mehr.



  • @5cript sagte in funktion , quadratisches mittel:

    @hustbaer

    ich verstehe deinen Standpunkt nicht.
    Folgendes kommt sogar oft vor:

    std::vector <T> v(n);
    // std::copy from to
    // std::fill
    // for from to (<- das gleiche nur zu fuß)
    // ...
    

    Der Schnippsel unterschlägt leider den relevanten Teil.

    Defensives Programmieren sehe ich viel gefährlicher. Beim Programmieren "Angst" zu haben ist keine gute Einstellung.

    Was hat die Vermeidung von Duplizierung einer Konstante/eines Ausdrucks mit defensiv Programmieren zu tun? Ernst gemeinte Frage, ich erwarte eine ernst gemeinte Antwort wenn du darüber noch weiter diskutieren willst.

    Was ist so schlimm daran ein vector der korreten größe zu erzeugen und direkt zu initialisieren?

    Wenn man es richtig macht: nichts. Wieso zeigst du nicht mal ein Beispiel wo nicht die wichtigen Teile fehlen?



  • @hustbaer sagte in funktion , quadratisches mittel:

    Der Schnippsel unterschlägt leider den relevanten Teil.

    welcher ist?

    @hustbaer sagte in funktion , quadratisches mittel:

    Was hat die Vermeidung von Duplizierung einer Konstante/eines Ausdrucks mit defensiv Programmieren zu tun? Ernst gemeinte Frage, ich erwarte eine ernst gemeinte Antwort wenn du darüber noch weiter diskutieren willst.

    Welche Duplizierung? Wir scheinen komplett aneinander vorbei zu reden. weil was ich bisher laß war.
    "nicht resize oder den size constructor verwenden, sonder reserve, weil es könnte Fehler produzieren, wenn man danach versehentlich über die grenzen schreibt".



  • @5cript sagte in funktion , quadratisches mittel:

    @hustbaer sagte in funktion , quadratisches mittel:

    Der Schnippsel unterschlägt leider den relevanten Teil.

    welcher ist?

    Die Teile wo eingefügt (bzw. bei deiner Variante zugewiesen) wird. Von denen ist es schliesslich abhängig wie anfällig das ganze dafür ist bei Modifikationen kaputtzugehen.



  • BTW:
    @5cript sagte in funktion , quadratisches mittel:

    x.resize(n);
    
    for(int i=0; i<n; i++)
    {
        cout << i << " Wert: " << endl;
        cin >> x[i];
    }
    

    Das finde ich z.B. OK.

    Wobei man auch i < x.size() statt i < n schreiben könnte. Das wäre vermutlich nochmal besser.

    Bzw. falls man den Index nicht braucht dann gleich

    x.resize(n);
    
    for(auto& e : x)
        cin >> e;


  • @hustbaer sagte in funktion , quadratisches mittel:

    Die Teile wo eingefügt (bzw. bei deiner Variante zugewiesen) wird. Von denen ist es schliesslich abhängig wie anfällig das ganze dafür ist bei Modifikationen kaputtzugehen.

    0% Propability

    std::vector <T> v(n)
    std::fill(std::begin(v), std::end(v), [](*...*/){/*...*/});
    
    std::vector <T> v(/*size of source*/)
    std::copy(std::begin(source), std::end(source), std::begin(v));
    
    std::vector <T> v(/*size of source*/);
    std::transform(std::begin(source), std::end(source), std::begin(v), std::end(v), [](/*...*/){/*...*/});
    
    std::vector <T> v(/*size of source*/);
    // using boost zip_iterator for parallel iteration
    

    ...

    @hustbaer sagte in funktion , quadratisches mittel:

    Vorher Grösse ausrechnen und dann reinschreiben ist potentiell fehleranfällig, da man die Grösse dann an zwei Stellen im Code dupliziert hat

    EDIT: aarggghh, das passt nicht alles direkt aufs anfangsproblem, aber das steht oben ja schon von mir und hab ich abgehakt.



  • @5cript
    Ja, deine Beispiele sind OK. Da wird aber auch nirgends vorher die Grösse ausgerechnet.

    Glaub mir bitte, ich hab schon genug Fälle gesehen wo beknacktes Zeug stand wie

    vec.resize(a - 1 + b * 2);
    
    size_t i = 0;
    
    for (size_t j = 1; j < a; j++)
        vec[i++] = ...;
    
    for (size_t j = 0; j < b; j++) {
         vec[i++] = ...;
         vec[i++] = ...;
    }
    

    Sowas finde ich nicht OK.

    Und dazwischen, also zwischen solchem Code und dem den du gezeigt hast gibt es halt eine Grauzone.



  • @hustbaer sagte in funktion , quadratisches mittel:

    Glaub mir bitte, ich hab schon genug Fälle gesehen wo beknacktes Zeug stand wie

    vec.resize(a - 1 + b * 2);
    
    size_t i = 0;
    
    for (size_t j = 1; j < a; j++)
        vec[i++] = ...;
    
    for (size_t j = 0; j < b; j++) {
         vec[i++] = ...;
         vec[i++] = ...;
    }
    

    mildes igitt.
    Hmmm. Unter den Umständen stimme ich dir zu.



  • Ich meine, du hast halt in diesem Thread geschrieben

    Grundsätzlich: Wenn man die größe des vectors von anfang an kennt, dann in der größe erstellen oder resizen. Es tut nicht weh das immer zu machen.
    Denn push_back bedeutet potentiell mehrere Vergrößerungen, sprich reallokationen.

    (Emphasis by me)

    Und das war mit zu allgemein/absolut formuliert. Wenn es einfach und sicher geht, klar, wieso nicht? Wenn es nicht einfach geht aber man sich die Arbeit mache es irgendwie kompliziert und sicher zu machen halte ich es für eine sinnlose Optimierung. Und wenn man es nicht sicher macht, dann ... ist es eben fehleranfällig.

    Das ist alles.



  • @hustbaer sagte in funktion , quadratisches mittel:

    Und das war mit zu allgemein/absolut formuliert.

    @5cript sagte in funktion , quadratisches mittel:

    mildes igitt.
    Hmmm. Unter den Umständen stimme ich dir zu.

    Ok. Jetzt haben wir wieder den gemeinsamen Faden gefunden.
    Ja das war zu allgemein formuliert.
    Im Kopf hatte ich was in meinen Beispielen zu lesen ist im Gegensatz zu:

    std::vector v;
    //v.reserve(/*size of source*/);
    for (IterType i = begin; i != end; ++i)
    {
        v.push_back(source[i]);
    }
    

Anmelden zum Antworten