2017-03-01 14 views
0

私はこれらの大きな市場データのpcapファイルを持っています。平均してそれぞれ20GBです。ファイルはパケットに分割されます。パケットはヘッダーとメッセージに分割されます。メッセージはヘッダーとフィールドに分かれています。フィールドはフィールドコードとフィールド値に分割されます。文字ベクトルを文字列に変換する最も効率的な方法

私は一度に1文字ずつファイルを読みます。私は、文字を読み込み、4つのコールバック関数、on_packet_delimiter、on_header_char、on_message_delimiter、on_message_charにconst refで文字を渡すファイルリーダークラスを持っています。メッセージオブジェクトは、同様の機能を使用してフィールドを構築します。

ここまで私は、文字を読んで何もしないのと比べて、効率がほとんど損なわれていないことに気付きました。

メッセージヘッダーを処理してメッセージの楽器シンボルを抽出している部分のコードは、処理がかなり遅くなります。 on_message_header_complete()

void message::add_char(const char& c) 
{ 
    if (!message_header_complete) { 
    if (is_first_char) { 
     is_first_char = false; 
     if (is_lower_case(c)) { 
     first_prefix = c; 
     } else { 
     symbol_vector.push_back(c); 
     } 
    } else if (is_field_delimiter(c)) { 
     on_message_header_complete(); 
     on_field_delimiter(c); 
    } else { 
     symbol_vector.push_back(c); 
    } 
    } else { 
    // header complete, collect field information 
    if (is_field_delimiter(c)) { 
     on_field_delimiter(c); 
    } else { 
     fp->add_char(c); 
    } 
    } 
} 

... 

void message::on_message_header_complete() 
{ 
    message_header_complete = true; 
    symbol.assign(symbol_vector.begin(),symbol_vector.end()); 
} 

... 

私はsymbol_vectorに文字を供給しています。ヘッダーが完成したら、Iteratorを使って文字列に変換します。これはこれを行う最も効率的な方法ですか?

+0

[この 'std :: string'コンストラクタのリファレンス](http://en.cppreference.com/w/cpp/string/basic_string/basic_string)を参考にしてください。 –

+0

'symbol'がメンバ変数で空であれば、これは効率的です。 – StoryTeller

+3

私はコピーを含む最も効率的な答えを出しましたが、最初に 'std :: vector 'が必要な理由はまだ分かりません。最初から 'std :: string'を使うだけです! –

答えて

1

:ベクトルがするようにはstd :: stringは非常に似て振る舞う必要があります。あなたが効率のためにそれを使用するつもりならば、文字列クラスで '予約'機能さえも利用できます。

std::string s; 
char c = 's'; 
s += c; 

あなたは、あなたのメンバーに直接文字を追加することができ、あなたは大丈夫です:

文字を追加すると、それが得ることができると同じように簡単です。しかし、文字列全体が収集されるまでメンバをクリーンに保つには、ベクトルの代わりにstd :: stringオブジェクトを使用する必要があります。その後、一時文字列に文字を追加し、完了時にスワップの内容を入力することができます。コピーしない、ポインタ交換(容量やサイズなどの追加データ)。

+0

おかげで、この方法と.appendの両方は、スピードを大幅に向上させます。平均で20736ミリ秒対35459ミリ秒。私はこれを取るつもりです。それはシンプルさと、それが平均10回の比較に比べて20ms速いからです。私のテストファイルの1000倍の大きさのメインファイルが少しずつカウントされます。 – bkarj

+0

あなたはスワップ機能について言及しました。この機能はコピーしませんが、ポインタを交換するだけです。私は興味があります。文字列を返す関数があり、その関数に戻り文字列を作成するローカル文字列変数があるとしましょう。一時的な文字列変数を返すと、コンパイラはそれを返された値にコピーしますか、それともスワップしますか? – bkarj

+1

@bkarjそれはスワップしますが、C++ 11以降に限ります。より古い標準に対してコンパイルすると、コピーが作成されます。 [rvalue references](http://thbecker.net/articles/rvalue_references/section_01.html)を見てください(非常に短いです:std :: stringは、2ページで述べたこの「ミステリータイプ」のコンストラクタ/代入演算子を提供します)。 )。セマンティクスは、一般的にはこの動作が呼び出されるときに移動するため、基になるデータ型がサポートする場合にのみ適用されることに注意してください。 – Aconcagua

1

方法について:これは動作しますが、あなたが最初の場所でのベクトルを使用する必要がある理由

std::string myStr(myVec.begin(), myVec.end()); 

、私は理解していません。最初からstd::stringを使用し、文字または文字列を追加するにはmyStr.append()を使用してください。

はここでの例です:量子物理学者の答えに加えて

std::string myStr = "abcd"; 
myStr.append(1,'e'); 
myStr.append(std::string("fghi")); 
//now myStr is "abcdefghi" 
関連する問題