web-dev-qa-db-ja.com

memcpyを使用してprotobufから繰り返しフィールドにstd :: vectorをコピーします

最初はこの単純なprotobufファイルがあります

message messagetest
{
    ...
    repeated float samples = 6;
    ....
}

このメソッドでヘッダーファイルを作成します

    //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();

私が基本的に行っているのは、forループですべてのデータを1つずつコピーすることです。

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

しかし、私はmemcpyのような方法を使用してコピープロセスを加速したいと思います。それは私の頭に浮かぶアイデアです。それが完全に間違っている場合は私を訂正してください。ヘッダーファイルの最後の宣言は次のとおりです。

inline ::google::protobuf::RepeatedField< float >* mutable_samples();

この方法が何をするのかわかりません(スキル不足)。しかし、それは一種のベクトルのように見えます。多分それが私の問題の解決策です。もしそうなら、私はそれを実装する方法がわかりません。


解決済みの編集

Memcpyは、メソッド呼び出しが1つあり、データをコピーするため、いずれの場合も高速です。 「fMessage.add_samples()」メソッドを1000回呼び出さなければならないforループと比較して。

このアプローチの欠点の1つは、サンプル用のデータを予約するためにベクターのサイズを知っている必要があることですが、プログラムでfMessage.sampleのメモリを割り当てることができます(これは私にとってはうまくいきます)。

fMessage.mutable_samples()->Reserve(fData.size());

for (int j = 0; j < fData.size(); j++)
{
   fMessage.add_samples(0);          
}

これで、whileループでストリームからデータを取得し、memcpyを使用してデータコンストラクターにコピーできます。

while(42)
{
   //fancy streaming things to get vector fData

  memcpy(fMessage.mutable_samples()->mutable_data(),
         &fData[0],
         sizeof(float)*fData.size());
}
12
akristmann

これはまだここになく、私はワンライナーが好きなので:

*fMessage.mutable_samples() = {fData.begin(), fData.end()};
18
mgild

次のように、ベクトルを繰り返しフィールドにコピーする最短の方法を見つけました。

google::protobuf::RepeatedField<float> data(fData.begin(), fData.end());
fMessage.mutable_samples()->Swap(&data);

初期反復を回避し、値を0に設定するため、おそらくあなたよりも高速です。

16
nazgul
fMessage.mutable_samples()

サンプルのポインタの配列を返します:[* sample1、* sample2、sample3、...]。

&fData[0]

fDataの最初の要素のアドレスです。

memcpy(fMessage.mutable_samples()->mutable_data(),
     &fData[0],
     sizeof(float)*fData.size());

したがって、上記のコードでfDataからfMessageにデータを正常に入力できるとは思いません。それは完全に間違っています!

0
Arthur George