最初は s の配列であったシリアル メモリ 2D 配列のクラスがありint
ます。別の型の同様の配列が必要になったので、テンプレートを使用してクラスを書き直しました。唯一の違いは、格納されたオブジェクトのタイプにあります。
template <class T>
class Serial2DArray
{
...
T ** Content;
}
コンテンツを処理するいくつかのテスト関数があります。たとえば、配列内のすべての要素を無効にする関数です (それらはクラス メンバーではなく、Serial2DArray<int>
オブジェクトを操作する関数の外部にあります。1- 2% 遅い - クラス内の他のすべてのコードは変更されていません。唯一の違いは、以前は単なる通常のクラスでしたがint ** Content
、現在はテンプレートになっていることです。
似たような質問: C++ テンプレートはプログラムを遅くしますか? -コンパイルだけが遅くなるという意見があります(コンパイラがコード内で見つけたそれぞれのクラスを生成する理由がわかります)が、ここではプログラムが実行時に遅くなることがわかります-合理的な説明はありますか?
Upd: ここで問題を少し絞り込みました: https://stackoverflow.com/a/11058672/1200000
Upd2: コメントで述べたように、遅くなった関数は次のとおりです。
#include <windows.h>
#include <mmsystem.h>
...
int Size = G_Width * G_Height * sizeof(int);
DWORD StartTime = timeGetTime();
for(int i=0; i<100; ++i)
{
FillMemory(TestArray.Content[0], Size, 0);
}
MeasuredTime = timeGetTime() - StartTime;
実際のクラス テンプレートは次のとおりです。
#include <malloc.h>
template <class T>
class Serial2DArray
{
public:
Serial2DArray()
{
Content = NULL;
Width = 0;
Height = 0;
}
Serial2DArray(int _Width, int _Height)
{
Initialize(_Width, _Height);
}
~Serial2DArray()
{
Deinitialize();
}
T ** Content;
int GetWidth()
{
return Width;
}
int GetHeight()
{
return Height;
}
int Initialize(int _Width, int _Height)
{
// creating pointers to the beginning of each line
if((Content = (T **)malloc(_Height * sizeof(T *))) != NULL)
{
// allocating a single memory chunk for the whole array
if((Content[0] = (T *)malloc(_Width * _Height * sizeof(T))) != NULL)
{
// setting up line pointers' values
T * LineAddress = Content[0];
for(int i=0; i<_Height; ++i)
{
Content[i] = LineAddress; // faster than Content[i] =
LineAddress += _Width; // Content[0] + i * _Width;
}
// everything went ok, setting Width and Height values now
Width = _Width;
Height = _Height;
// success
return 1;
}
else
{
// insufficient memory available
// need to delete line pointers
free(Content);
return 0;
}
}
else
{
// insufficient memory available
return 0;
}
}
int Resize(int _Width, int _Height)
{
// deallocating previous array
Deinitialize();
// initializing a new one
return Initialize(_Width, _Height);
}
int Deinitialize()
{
// deleting the actual memory chunk of the array
free(Content[0]);
// deleting pointers to each line
free(Content);
// success
return 1;
}
private:
int Width;
int Height;
};
リクエストに応じて、バイナリ サイズの比較。
次のコードを使用します。
Serial2DArray<int> TestArray;
Serial2DArray<int> ZeroArray;
- 1 016 832 バイト。
次のコードを使用します。
Serial2DArray TestArray; // NOT-template class with ints
Serial2DArray ZeroArray; // methods are in class declaration
- 1 016 832 バイト
次のコードを使用します。
Serial2DArray<int> TestArray;
Serial2DArray<int> ZeroArray;
Serial2DArray<double> AnotherArray;
Serial2DArray<double> YetAnotherArray;
- 1 017 344 バイト