top of page
執筆者の写真神山 義尚

C++のポインタは本当に早いのか?

更新日:2021年9月21日


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配列等を使う事をお勧めします。

でも、ポインタの仕様が変更されて、使用できるようになった場合は、使用をお勧めします。理由は、早いからです。


何だか、悲しいですね・・・。



閲覧数:67回0件のコメント

最新記事

すべて表示

緊急避難時の持出品と、避難時の食事

#地震 #水害 #大雨 #火災 #山火事 #地鳴り #土砂崩れ #大雪 #緊急 #避難 #緊急避難 #持出品 #持ち出し品 #持出し品 #避難時の食事 #緊急避難時の食事 【持出品】 首相官邸の名前で、非常用持ち出し袋として、避難の際に持ち出すものとして、Webで公開してい...

国際関係の変化と日本の今後

#政治 #経済 #戦争 #平和 【世界情勢の変化】 ロシアがクリミア半島を併合しました。 これによって、ロシアが何か変な国になったと感じていました。 更に、ロシアは、ウクライナ全域を奪取すべく、戦争をしています。 そもそも、ゼレンスキー大統領が平和主義過ぎて、ロシアに所有し...

新資本主義は、間違っている

#政治 #経済 【新資本主義は、間違っている】 新資本主義、「企業さえ生き残ればそれで良い」と言う思想は、間違っています。 企業経営のエゴでしかありません。 個人の投資家を大事にしない資本主義なんて、分けのわからない思想が間違っている。 国民主権です。...

Comments


bottom of page