
akristmann
Zuerst habe ich diese einfache protobuf-Datei
message messagetest
{
...
repeated float samples = 6;
....
}
Was mit diesen Methoden eine Headerdatei erstellt
//repeated float samples = 6;
inline int samples_size() const;
inline void clear_samples();
static const int kSamplesFieldNumber = 6;
inline float samples(int index) const;
inline void set_samples(int index, float value);
inline void add_samples(float value);
inline const ::google::protobuf::RepeatedField< float >& samples() const;
inline ::google::protobuf::RepeatedField< float >* mutable_samples();
Was ich im Grunde tue, ist, alle Daten einzeln in eine for-Schleife zu kopieren.
int main(int argc, char** argv)
{
messagetest fMessage;
vector<float> fData (1000, 0);
// Create 1000 random values
for (int i = 0; i < fData.size(); i++)
{
fData[i] = rand() % 1001;
}
for (int j = 0; j < fData.size(); j++)
{
fMessage.add_samples(fData[j]);
}
return 0;
}
Aber ich möchte eine Methode wie memcpy verwenden, um den Kopiervorgang zu beschleunigen. Es ist nur eine Idee, die mir in den Sinn kommt. Wenn es völlig falsch ist, korrigiere mich. Die letzte Deklaration in der Headerdatei lautet:
inline ::google::protobuf::RepeatedField< float >* mutable_samples();
Ich habe keine Ahnung, was diese Methode bewirkt (Mangel an Geschick). Aber es sieht irgendwie aus wie ein Vektor. Vielleicht ist das die Lösung für mein Problem. Wenn ja, habe ich keine Ahnung, wie ich das umsetzen soll.
Da dies noch nicht hier ist und ich Einzeiler mag:
*fMessage.mutable_samples() = {fData.begin(), fData.end()};

Nazgul
Ich habe den kürzesten Weg gefunden, den Vektor in das wiederholte Feld zu kopieren:
google::protobuf::RepeatedField<float> data(fData.begin(), fData.end());
fMessage.mutable_samples()->Swap(&data);
Es ist wahrscheinlich auch schneller als Ihres, da es die anfängliche Iteration und das Setzen von Werten auf 0 vermeidet.
Die Antwort von @mgild wird implizit die aufrufen RepeatedField(Iter begin, Iter end)
Konstruktor, um ein temporäres Element zu erstellen, das einer Verschiebung zugewiesen werden soll. Dasselbe gilt für die Antwort von @nazgul, die ausdrücklich erstellt ein temporäres RepeatedField und tauscht es aus.
Viel einfacher wäre es, die Erstellung eines neuen Objekts zu vermeiden:
fMessage.mutable_samples()->Add(fData.begin(), fData.end())
Wenn samples
Feld bereits nicht leer ist, können Sie anrufen Clear
Methode vor.
Intern verwendet dies std::copy
(so lange wie fData
ist ein Vorwärts-Iterator), ist also genauso schnell wie jede Memcpy-Implementierung, die Sie sich ausdenken.

David Toth
Als Alternative zu der ausgezeichneten Antwort von @mgild, Assign
kann auch in dieser Situation verwendet werden, sodass die Daten vor dem Verschieben nicht in ein temporäres kopiert werden.
fMessage.mutable_samples()->Assign(fData.begin(), fData.end())
Gutschrift für die Antwort von Marek R
fMessage.mutable_samples()
gibt ein Array von Zeigern von Samples zurück: [*sample1, *sample2, sample3, …].
&fData[0]
ist die Adresse des ersten Elements von fData.
memcpy(fMessage.mutable_samples()->mutable_data(),
&fData[0],
sizeof(float)*fData.size());
Ich glaube also nicht, dass der obige Code erfolgreich Daten von fData nach fMessage füllen kann. Es ist total falsch!
10155000cookie-checkKopieren Sie einen std::vector in ein wiederholtes Feld von protobuf mit memcpyyes
Haben Sie es profiliert und gesehen, dass es langsam ist? Haben Sie den kompilierten Code überprüft und festgestellt, dass er schlecht optimiert ist?
– Nicht zu gebrauchen
19. März 2013 um 13:23 Uhr