最近、ディスカッション中に、他のプログラマーからコードの変更を依頼されました。私は次のようなものを持っていました:
_if( mystring.size() == 0)
// do something
else
// do something else
_
議論は、文字列が空かどうかを検証するためのmystring.empty()
の使用に関するものでした。ここで、string.empty()
はより冗長で読みやすいコードであると主張できることに同意しますが、パフォーマンス上の利点はありますか?
私はいくつかの掘り下げを行い、私の質問に関連するこれらの2つの答えを見つけました:
どちらの回答も、string.empty()
はstring.size() == 0
に比べて読みやすく、パフォーマンス上の利点がないという私の主張を強調しています。
文字列が空かどうかを検証するために内部ブールフラグを保持するstring
の実装があるかどうかを確認しますか否か?
または、いくつかの実装が使用する他の方法があります。それは私の主張を無効にしますか?
標準では、次のようにempty()
を定義しています。
bool empty()const noexcept;
戻り値:size()== 0。
あなたはそれを行わない何かを見つけるのに苦労するでしょうし、一定の時間の操作であるため、パフォーマンスの違いは無視できます。合理的な実装では、両方ともまったく同じアセンブリにコンパイルされると思います。
そうは言っても、empty()
は明確かつ明示的です。読みやすくするために、size() == 0
(または!size()
)よりも優先する必要があります。
さて、これはかなり些細なことですが、同僚が口にするどんな議論もあなたを驚かせないように徹底的にカバーしようと思います...
いつものように、プロファイリングで本当にreallyが気にしなければならなかったことが判明した場合は、以下を測定します:therecould違いがあります(以下を参照)。しかし、証明されていない、問題が遅いコードの一般的なコードレビュー状況では、未解決の問題は次のとおりです。
他の一部のコンテナ(C++ 03リストではあるがC++ 11ではない)では、size()
の方がempty()
よりも効率が悪いため、empty()
よりもsize()
の方が優先されるコーディングヒント] _一般に、後でコンテナを切り替える必要がある場合(またはコンテナのタイプが異なるテンプレートに処理を一般化する場合)は、効率を維持するために変更を加える必要はありません。
どちらがテストを想像するためのより自然な方法を反映していますか? -最初に思いついたことだけでなく、size()
はempty()
の使用に慣れていないためですが、周囲のコードロジックに100%集中していると、size()
またはempty()
うまく収まりますか?たとえば、これはsize()
のいくつかのテストの1つであり、一貫性を保つことが好きなため、またはサイズの観点から従来から表現されている有名なアルゴリズムまたは式を実装しているためです。一貫性があると、精神的なノイズ/労力が軽減される可能性があります。式に対する実装の検証において。
ほとんどの場合、上記の要因は重要ではなく、コードレビューで問題を提起することは本当に時間の無駄です。
考えられるパフォーマンスの違い
標準は機能的な同等性を要求しますが、一部の実装mightはそれらを異なる方法で実装しますが、私は苦労して、これまでのところ、そうするための特にもっともらしい理由を文書化できませんでした。
C++ 11には、実装の選択に影響を与える他の関数の動作に対するC++ 03よりも多くの制約があります。data()
はNULで終了する必要があります(以前はc_str()
でした)、[size()]
は有効なインデックスであり、NUL文字への参照を返す必要があります。さまざまな微妙な理由により、これらの制限により、empty()
がsize()
より速くなる可能性がさらに高くなります。
とにかく-あなたが気にする必要があるかどうかを測定します。