ない(おそらくunanswerable)の質問に直接答えが、あなたが興味があるかもしれない。
std::string
は、短い文字列に使用する(ご使用の場合)スタック上のメモリを事前に割り当てるいくつかのヒント。文字列が長すぎる場合は、ヒープからメモリを割り当てます(パフォーマンスの低下)。
文字列がさらに大きくなると、再割り当てが必要になることがあります。
ループ内のバッファとして文字列(または任意のコンテナ)を使用する場合、1つのオブジェクトを割り当てて再利用する方がはるかに意味があります。これは、文字列の概念がcapacity()
(つまり、どれくらいのメモリを所有しているか)とsize()
(私が使用しているメモリの量)という概念があるからです。
clear()
文字列の場合、capacity()
は縮小されません。つまり、同じループ内で1回または2回だけメモリ割り当てコストを支払うことになります。
さらに、substr()
は新しい文字列を割り当てます。短い3文字の文字列については、これは問題ではありませんが(上記を参照してください)、長い文字列の場合はメモリ割り当てコストが発生します。
ので(パフォーマンスがあなたの#1の目標である場合)、タイトなループ内:
反復あたり1つの文字列バッファを再使用します。
substrを避け、明示的に範囲を比較します。
ので、このような何か:
#include <string>
extern void build_string(std::wstring& target);
void foo()
{
std::wstring insert;
insert.reserve(10000); // or however long you anticipate the longest string to be.
//this is a very minor optimisation. don't worry if you get it wrong
for(;;) // more idiomatic
{
static constexpr auto sequence = L"`/`";
static constexpr auto sequence_length = std::extent<decltype(sequence)>::value - 1;
insert.clear(); // assuming we don't want residue from the previous iteration
build_string(insert); // pass a reference
//...
if (insert.empty()){
//...
break; // ?
}
else if (insert.size() >= sequence_length // important!
and std::equal(insert.begin(),
std::next(insert.begin(), sequence_length),
sequence)) // will compile to memcmp
{
}
else if (insert[0] == L'\t'){
//...
}
else if (insert[0] == L'#') {
break;
}
else { /*...*/ }
}
}
あなたがあなたの目標について詳しく説明できますか?あなたは何を目指していますか? – Charles
CタグをC++の質問に載せないでください。 –
std :: stringview in C++ 17では、これはかなり高速になります。 –