はじめに
Javaを学習していた際、「文字列の結合に+演算子を使うと処理が遅くなるため、専用のメソッドを使うべき」と教わりました。
以前にC++を勉強していたこともあり、この最適化の考え方がC++にも当てはまるのか気になり、簡単な実験を行ってみることにしました。
実験方法
文字列の連結方法による処理速度の違いを確認するため、C++のstd::string
型を用いて、2つの連結方法—+=
演算子とappend()
メソッド—の実行時間を比較するテストを行いました。
それぞれの手法で、1回の連結につき "a" を追加する処理を、10 回から 10,000,000 回まで段階的に繰り返し、所要時間を計測しました。
サンプルコード
サンプルコード
#include <iostream>
#include <chrono>
#include <string>
constexpr int MAX = 10000000;
void benchmark(const std::string& label, auto func) {
auto start = std::chrono::steady_clock::now();
std::string str;
for (int i = 0; i < MAX; ++i) {
func(str);
}
auto end = std::chrono::steady_clock::now();
auto ms = std::chrono::duration<double, std::milli>(end - start).count();
std::cout << label << ": " << ms << " ms\n";
}
int main() {
benchmark("str += \"a\"", [](std::string& s) { s += "a"; });
benchmark("str.append(\"a\")", [](std::string& s) { s.append("a"); });
return 0;
}
結果
実行時間の計測結果(ms)
繰り返し回数 | 10 | 100 | 1,000 | 10,000 | 100,000 | 1,000,000 | 10,000,000 |
---|---|---|---|---|---|---|---|
+= | 0.0022 | 0.0129 | 0.0631 | 0.5326 | 5.6296 | 48.597 | 560.996 |
.append | 0.001 | 0.0082 | 0.0549 | 0.474 | 4.5976 | 46.3441 | 475.47 |
実験の結果、文字列の連結処理では+=
演算子よりもappend()
メソッドのほうが一貫して高速であることが確認できました。特に、繰り返し回数が増えるほど、その差が大きくなっていく傾向が見られました。
この違いは、+=が演算子オーバーロードによって実装されており、使用時に暗黙的な型変換や一時オブジェクトの生成が発生するためと考えられます。
以上のことから、C++においてもJavaと同様に、大量の文字列連結を行う際はappend()
の使用が推奨されると言えます。
追記
コメントでいただいた内容から、char*
型を受け取るoperator+=
の効果として、実際にはappend()
メソッドを呼び出しているということが分かりました。
この場合、+=
演算子が1段階多く関数呼び出しを行うため、その分、計測結果に反映されている可能性があります。
@SaitoAtsushi さん、ありがとうございました。
最後に
今回の実験は、文字列 "a" を繰り返し追加するというシンプルなものであり、他の条件やアプローチを取った場合には異なる結果が得られる可能性もあります。
もし他にも有効な方法や補足すべき点があれば、ぜひ教えていただけると幸いです。