MFCとは、完全な機械語に翻訳されるプログラム言語です。ネイティブなプログラム言語として知られている言語のMicrosoftのC++言語です。
Microsoftの言語のC++には、CLRと言うC++がありますが、CLRは、ガベージコレクターを使用している.NetFrameworkを使ってプログラミングする事が出来る言語です。CLRのC++言語の事をマネージなプログラム言語と言います。この為、CLRのC++言語の処理速度は、C#やVBと殆ど同じ処理速度で動作する言語です。なので、このブログては、C#の処理速度をマネージな言語の処理速度とします。つまり、あえて、VBやCLRで処理速度を計測しないと言う事です。
上記、画像は、当社のFreeソフトの「MFC ベンチマーク」を実行して処理速度計測をした結果図です。
このブログで説明する上記、画像のソフトウェアは、Vector株式会社のWebサイトでFreeソフトとしてダウンロードできます。
ダウンロードサイトは、以下の通りです。
皆さんのパソコンにインストールしてお使い下さい。
どんな処理を書くと早いプログラムになるのか等のご参考になればと思っております。
さて、プログラムの詳細です。
以下の様なプログラムの内容になっています。
m_TextBox15.に、処理回数が入力されています。
void CArrayFastedDlg::OnBnClickedButton1()
{
// int[] newによる動的配列
CString CSDat(L"");
m_TextBox1.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
int* iDatH = new int[iLen];
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
iDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox1.SetWindowTextW(CSDat); // 表示
delete[] iDatH;
}
void CArrayFastedDlg::OnBnClickedButton2()
{
// vector<int>配列 push_back
CString CSDat(L"");
m_TextBox2.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
vector<int> ViDatH;
ViDatH.reserve(iLen); // メモリー確保
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
ViDatH.push_back(i);
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox2.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton4()
{
// vector<int>配列 push_back
CString CSDat(L"");
m_TextBox4.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
vector<int> ViDatH;
//ViDatH.reserve(iLen); // メモリー確保
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
ViDatH.push_back(i);
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox4.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton3()
{
// vector<int>配列 at()
CString CSDat(L"");
m_TextBox3.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
vector<int> ViDatH;
ViDatH.reserve(iLen); // メモリー確保
for (int i = 0; i < iLen; i++) {
ViDatH.push_back(0); //初期化
}
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
ViDatH.at(i) = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox3.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton5()
{
// vector<int>配列 []
CString CSDat(L"");
m_TextBox5.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
vector<int> ViDatH;
ViDatH.reserve(iLen); // メモリー確保
for (int i = 0; i < iLen; i++) {
ViDatH.push_back(0); //初期化
}
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
ViDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox5.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton6()
{
// CString[] new 動的配列 ポインタ
CString CSDat(L"");
m_TextBox6.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
int a = 0;
CString* CSDatH = new CString[iLen];
Start = std::chrono::system_clock::now();
for (CString *CSp = CSDatH; a < iLen; CSp++) {
CSDat.Format(L"%d", a); // int→CStringに変換
*CSp = CSDat;
a += 1;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox6.SetWindowTextW(CSDat); // 表示
delete[] CSDatH;
}
void CArrayFastedDlg::OnBnClickedButton7()
{
// array配列 (mallocで一部をヒープに移動するか、vector等を使用する)
CString CSDat(L"");
m_TextBox7.SetWindowTextW(CSDat); // クリア
std::chrono::system_clock::time_point Start, End;
double Time;
std::array<int, 100000> AiDatH = {};
Start = std::chrono::system_clock::now();
for (int i = 0; i < 100000; i++) {
AiDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox7.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton8()
{
// array配列 初期化した場合 (mallocで一部をヒープに移動するか、vector等を使用する)
CString CSDat(L"");
m_TextBox8.SetWindowTextW(CSDat); // クリア
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = 100000;
std::array<int, 100000> AiDatH = { 0 };
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
AiDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox8.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton9()
{
// int[] mallocによる動的配列
// 動的メモリー確保のmallocで配列を確保する事でコープ領域を使う事が出来る。
// でも落とし穴があるのでvectorを使用する方が良い
CString CSDat(L"");
m_TextBox9.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); // CString→intに変換
int* iDatH;
iDatH = (int*)malloc(sizeof(int) * iLen); // 動的メモリーの確保
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
iDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox9.SetWindowTextW(CSDat); // 表示
//int x = iDatH[9]; // テスト
free(iDatH);
}
void CArrayFastedDlg::OnBnClickedButton10()
{
// CString[] newによる動的配列
CString CSDat(L"");
m_TextBox10.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
CString* CSDatH = new CString[iLen];
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
CSDat.Format(L"%d", i); // int→CStringに変換
CSDatH[i] = CSDat;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox10.SetWindowTextW(CSDat); // 表示
delete[] CSDatH;
}
void CArrayFastedDlg::OnBnClickedButton11()
{
// int[] new 動的配列 ポインタ
CString CSDat(L"");
m_TextBox11.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
int a = 0;
int* iDatH = new int[iLen];
Start = std::chrono::system_clock::now();
for (int* ip = iDatH; a < iLen; ip++) {
*ip = a;
a += 1;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox11.SetWindowTextW(CSDat); // 表示
delete[] iDatH;
}
void CArrayFastedDlg::OnBnClickedButton12()
{
// int[100000] 静的配列
CString CSDat(L"");
m_TextBox12.SetWindowTextW(CSDat); // クリア
std::chrono::system_clock::time_point Start, End;
double Time;
int iDatH[100000];
Start = std::chrono::system_clock::now();
for (int i = 0; i < 100000; i++) {
iDatH[i] = i;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox12.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton13()
{
// CString[100000] 静的配列
CString CSDat(L"");
m_TextBox13.SetWindowTextW(CSDat); // クリア
std::chrono::system_clock::time_point Start, End;
double Time;
CString CSDatH[100000];
Start = std::chrono::system_clock::now();
for (int i = 0; i < 100000; i++) {
CSDat.Format(L"%d", i); // int→CStringに変換
CSDatH[i] = CSDat;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox13.SetWindowTextW(CSDat); // 表示
}
void CArrayFastedDlg::OnBnClickedButton15()
{
// char[] new 動的配列 ポインタ
CString CSDat(L"");
m_TextBox14.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
char* chDatH = new char[iLen];
CString* CSDatH = new CString[iLen];
int a = 0;
char* chW;
Start = std::chrono::system_clock::now();
for (char* chp = chDatH; a < iLen; chp++) {
CSDat.Format(L"%d", a); // int→CStringに変換
CStringA CSAData(CSDat);
const char* cchData = CSAData;
chW = const_cast<char*>(cchData); //constを削除するキャスト
chp = chW;
CSDatH[a] = chp;
a++;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox14.SetWindowTextW(CSDat); // 表示
delete[] chDatH;
delete[] CSDatH;
}
void CArrayFastedDlg::OnBnClickedButton16()
{
// char[] new 動的配列
CString CSDat(L"");
m_TextBox16.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
CString* CSDatH = new CString[iLen];
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
CSDat.Format(L"%d", i); // int→CStringに変換
CStringA CSAData(CSDat);
const char* cchData = CSAData;
chDat = const_cast<char*>(cchData); //constを削除するキャスト
CSDatH[i] = chDat;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox16.SetWindowTextW(CSDat); // 表示
delete[] CSDatH;
}
void CArrayFastedDlg::OnBnClickedButton17()
{
// string[] new 動的配列
CString CSDat(L"");
m_TextBox17.SetWindowTextW(CSDat); // クリア
m_TextBox15.GetWindowTextW(CSDat); // 値を取得
std::chrono::system_clock::time_point Start, End;
double Time;
int iLen = _ttoi(CSDat); //CString→intに変換;
char* chDat;
string* strDatH = new string[iLen];
Start = std::chrono::system_clock::now();
for (int i = 0; i < iLen; i++) {
CSDat.Format(L"%d", i); // int→CStringに変換
CStringA CSADat(CSDat); //ASCIIに変換
string strDat(CSADat); //stringに変換
strDatH[i] = strDat;
}
End = std::chrono::system_clock::now();
Time = (double)std::chrono::duration_cast<std::chrono::microseconds>(End - Start).count();
Time = Time / 1000;
CSDat.Format(L"%.3f", Time); //Double→CStringに変換 小数点第#位まで表示の場合
CSDat = CSDat + L"ms";
m_TextBox17.SetWindowTextW(CSDat); // 表示
delete[] strDatH;
}
以上が、MFC ベンチマークで使用したプログラムです。
やはり、ポインタは早いと言う結果でした。
しかし、array配列の速さは驚異的早さです。
こんなにも早いとは思ってもいませんでした。
しかし、array配列は、問題が多い様です。
array配列を使わずに、
vector配列を使う事をMicrosoftは推薦しています。
以上、ポインタは本当に早いのか?でした。
2021年9月21日 追記
突然出ずか、マイクロソフトがプログラム言語の仕様を変更した様です。
今まで早かった、ポインタが異常に遅くなり、計算結果が表示しにくくなり、その上、計算結果がめちゃくちゃになると言う現象が発生する様になりました。
WindowsAPIやマイクロソフト提供のプログラムには、相変わらず、&を使用しているにも拘らず、どうやら、ポインタを使うなと言う仕様変更の様です。
ポインタは、アンセーフコードです。いきなり、電源を落とすとメモリーが破損する場合がある危険なコードです。Windowsにも、当たり前の様に使われている技術ですが、使わない方が無難なので、使わない事をお勧めします。
静的変数や静的配列やvector配列等を使う事をお勧めします。
でも、ポインタの仕様が変更されて、使用できるようになった場合は、使用をお勧めします。理由は、早いからです。
何だか、悲しいですね・・・。
Comments