vector zu int



  • Ich habe einen Vector dessen Inhalt empfangene Bytes aus einer Übertragung sind.
    Entweder ist in vecBytes[0] das LSB oder das MSB, was ich aber weiß.

    Gehen wir jetzt einfach davon aus, dass der Vector in einen int64 umgewandelt werden soll. Mein Ansatz;

    std::int64_t* value // Funktionsparameter
    
    *value = 0;
    memcpy(value, vecBytes.data(), vecBytes.size());
    

    Das ist aber eher c-Style. Deswegen habe ich folgendes versucht:

    std::int64_t* value // Funktionsparameter
    
    *value = 0;
    std::copy(vecBytes.begin(), vecBytes.end(), value);
    

    1.) Frage:
    Hier wird aber lediglich das erste Byte kopiert 😕 ? Warum?

    2.) Frage
    Wird std::copy deutlich langsamer sein, weil hier Iteratoren in einer while-Schleife in copy verwendet werden? Ich meine memcpy ist hier ja absolut schnell, da über data direkt auf die Daten zugegriffen werden kann.



  • Wenn schon, dann besser

    *value = reinterpret_cast<std::int64_t>(vecBytes.data());
    

    Bei dem copy zerschießt du dir den Speicher, denn der 3. Parameter wird als Output-Iterator verwendet: copy
    Du müßtest auch hier den 3. Parameter als "char *" casten.

    Auch memcpy verwendet intern eine Schleife, nur daß diese so optimiert ist, daß sie möglichst große Blöcke (entsprechend der Registerbreite) kopiert. Dafür ist aber der Prefix und Postfix-Code wegen dem Alignment etwas umfangreicher.

    Edit: irgendwie lauert heute hier der Schreibteufel...



  • Vectorianer schrieb:

    std::int64_t* value // Funktionsparameter
    
    *value = 0;
    std::copy(vecBytes.begin(), vecBytes.end(), value);
    

    1.) Frage:
    Hier wird aber lediglich das erste Byte kopiert 😕 ? Warum?

    es werden alle Bytes kopiert, nur nicht dahin, wo Du meinst. Das zweite Byte landet bei *(value+1) - also in einem std::int64_t -Wert, der hinter dem steht, auf den value zeigt.

    Abhilfe:

    std::int64_t* value // Funktionsparameter
    *value = 0; // sollte unnötig sein; besser: assert( vecBytes.size(), sizeof(std::int64) );
    std::copy(vecBytes.begin(), vecBytes.end(), reinterpret_cast< char* >(value) );
    

    Vectorianer schrieb:

    2.) Frage
    Wird std::copy deutlich langsamer sein, weil hier Iteratoren in einer while-Schleife in copy verwendet werden? Ich meine memcpy ist hier ja absolut schnell, da über data direkt auf die Daten zugegriffen werden kann.

    Vertraue den Leuten, die für Dich die Implementierung der Standard-Algorithmen geschrieben haben! - es muss gar nicht langsamer sein, kann aber.



  • Vielen Dank, jetzt sehe ich den Fehler beim Pointer auch... 😕


  • Mod

    Höchstwahrscheinlich wird std::copy übrigens zu einem memcpy, weil entweder die Implementierung von std::copy selbst erkennt, dass da PODs kopiert werden (mittels Templatemagie) oder weil der Optimierer die von einem naiv implementierten std::copy erzeugte Schleife als ein selbstgeschriebenes memcpy erkennt und durch die interne Version ersetzt.


Log in to reply