技術情報ブログ
技術情報ブログ 2022年5月 アーカイブ
C++ CString 文字列比較ってどれが速いの?
2022/05/11
はじめまして、富山オフィスの小坂です。
今年の4月で入社11年目になりました。
自分はまだまだ若い気持ちでいますが、新入社員の方を見ると歳を感じますね...。
さて、久しぶりではありますが技術ブログの更新です。
前回の更新が5年前のようで...スミマセン。
今年の4月で入社11年目になりました。
自分はまだまだ若い気持ちでいますが、新入社員の方を見ると歳を感じますね...。
さて、久しぶりではありますが技術ブログの更新です。
前回の更新が5年前のようで...スミマセン。
復帰第1回目のテーマは...
「C++ CString 文字列比較ってどれが速いの?」
「C++ CString 文字列比較ってどれが速いの?」
Windowsのアプリ開発でよく使われているライブラリと言えば「MFC」が思い浮かぶと思います。(もしくはATL)
更にその中で、文字列を扱うクラスと言えば「CString」がありますね。
サイズを気にせず代入や結合が簡単にでき、フォーマットや文字列比較もできるという、至れり尽くせりな便利クラスです。
ということで、今回は「CString」について紹介していきたいと思います。
といっても全部紹介していると日が暮れるので「文字列比較」、更にはその「処理速度」にスポットを当てて話をしたいと思います。
更にその中で、文字列を扱うクラスと言えば「CString」がありますね。
サイズを気にせず代入や結合が簡単にでき、フォーマットや文字列比較もできるという、至れり尽くせりな便利クラスです。
ということで、今回は「CString」について紹介していきたいと思います。
といっても全部紹介していると日が暮れるので「文字列比較」、更にはその「処理速度」にスポットを当てて話をしたいと思います。
文字列比較でよく見るコードは以下のような比較演算子を使った形ですね。
上記のようなコードでもプログラム的に問題はありません。
しかし処理速度の観点から見ると、もっと良いコードが書けます。
ではどのようなコードが速いのか?
検証を行ってみたので、その結果を紹介したいと思います。
- CString str1 = _T("abc");
- CString str2 = _T("123");
- bool bSame = false;
- if (str1 == str2) {
- bSame = true;
- }
上記のようなコードでもプログラム的に問題はありません。
しかし処理速度の観点から見ると、もっと良いコードが書けます。
ではどのようなコードが速いのか?
検証を行ってみたので、その結果を紹介したいと思います。
【検証内容】
以下の文字列の比較を 1,000,000回 行った速度を計測。
Vdk4jQnifyheeUVSJMAD2FdUXyCfR9HRTACieCMBVDguC3ALbU
vDK4JqNIFYHEEuvsjmad2fDuxYcFr9hrtacIEcmbvdGUc3alBu
使用した関数は以下の4つ。
Vdk4jQnifyheeUVSJMAD2FdUXyCfR9HRTACieCMBVDguC3ALbU
vDK4JqNIFYHEEuvsjmad2fDuxYcFr9hrtacIEcmbvdGUc3alBu
使用した関数は以下の4つ。
- Cstring::Compare
- Cstring::CompareNoCase
- _tcscmp
- CStringの等価演算子(==)
【検証コード】
比較結果をbool型の変数に代入するだけのシンプルなコードです。
測定する関数以外のコードはコメントアウトしています。
測定する関数以外のコードはコメントアウトしています。
- bool bSame = false;
- CString str1 = _T("Vdk4jQnifyheeUVSJMAD2FdUXyCfR9HRTACieCMBVDguC3ALbU");
- CString str2 = _T("vDK4JqNIFYHEEuvsjmad2fDuxYcFr9hrtacIEcmbvdGUc3alBu");
- // 測定start
- auto start = std::chrono::system_clock::now();
- for (int i = 0; i < 1000000; i++) {
- //bSame = (0 == str1.Compare(str2));
- //bSame = (0 == str1.CompareNoCase(str2));
- //bSame = (0 == _tcscmp(str1, str2));
- bSame = (str1 == str2);
- }
- // 測定end
- auto end = std::chrono::system_clock::now();
- // ミリ秒→秒 変換
- double dSec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() * 0.001;
- // 出力
- CString strResult = _T("");
- strResult.Format(_T("%lf"), dSec);
- ::AfxMessageBox(strResult);
【検証結果】
結論:_tcscmpが一番速い
上記の結果を見ると、基本的には「_tcscmp」を使うのが良さそうですね!
- Cstring::Compare 0.030
- Cstring::CompareNoCase 1.380
- _tcscmp 0.003
- CStringの等価演算子(==) 0.037
上記の結果を見ると、基本的には「_tcscmp」を使うのが良さそうですね!
【Tips】
今回の速度計測に用いたライブラリ「std::chrono」を簡単に紹介しておきます。
C++11から導入された標準ライブラリで、現在時刻の取得や時間計測ができます。
以下は処理時間を計測する時のサンプルコードです。
応用すればラップタイムの出力もできるので、ぜひ使ってみてください!
C++11から導入された標準ライブラリで、現在時刻の取得や時間計測ができます。
以下は処理時間を計測する時のサンプルコードです。
- auto start = std::chrono::system_clock::now();
- // この間に測定したい処理を書く
- auto end = std::chrono::system_clock::now();
- // 処理時間を取得(ミリ秒→秒に変換)
- double dSec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() * 0.001;
応用すればラップタイムの出力もできるので、ぜひ使ってみてください!
以上、いかがでしたでしょうか?
ちょっとテーマがピンポイントすぎたかもしれませんが、皆さんのお役に立てれば幸いです。
次回も乞うご期待ください!
ありがとうございましたm(_ _)m
ちょっとテーマがピンポイントすぎたかもしれませんが、皆さんのお役に立てれば幸いです。
次回も乞うご期待ください!
ありがとうございましたm(_ _)m
« 2017年2月 | 技術情報ブログトップページ | 技術情報ブログの記事一覧 | 2022年8月 »