使用模板重写的类会使程序变慢(在运行时)
A class rewritten with templates makes a program slower (in run-time)
我有一个串行存储器 2D 数组的类,它最初是一个 int
的数组。现在我需要另一种类型的类似数组,我用模板重写了类;唯一的区别是存储对象的类型:
template <class T>
class Serial2DArray
{
...
T ** Content;
}
我有几个处理 Content 的测试函数,例如,一个使数组中的所有元素无效的函数(它们不是类成员,它们是处理Serial2DArray<int>
对象的外部函数。我注意到现在它的工作速度慢了 1-2% - 类中的所有其他代码都保持不变,唯一的区别是早些时候它只是一个带有 int ** Content
的常规类,现在它是一个模板。
一个类似的问题:c++ 模板会让程序变慢吗? - 有意见认为只有编译变慢(我明白为什么,编译器为它在代码中找到的每个类生成类),但在这里我看到程序在运行时变慢 - 有什么合理的解释吗?
更新:问题在这里缩小了一点: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 字节
是的 - 随机基准测试可变性,更不用说整个程序较慢的事实可能与这个特定的类完全无关。
在容器类中使用模板可能会导致模板代码膨胀的已知问题。大致上,它可能会导致程序中出现更多页面错误,从而降低性能。
那你为什么要问?因为模板将为模板的每个类实例生成类,而不是一个类实例,从而在二进制产品中生成更多页面,如果您愿意,还可以生成更多代码页。这在统计上可能会导致更多的页面错误,具体取决于您的运行时执行。
查看一个类模板实例的二进制文件的大小,以及两个必须最重的实例。它将使您掌握新实例引入的新代码大小。
这是关于该主题的维基百科文章:代码膨胀文章。当强制编译器内联程序中的每个函数和方法时,如果编译器可以使用它,则问题可能是相同的。该标准试图通过将inline
关键字作为编译器每次都不得遵循的"请求"来防止这种情况。例如,GCC 以中间语言生成您的代码,以评估生成的二进制文件是否会导致代码膨胀,并可能因此丢弃内联请求。
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 为什么程序在 c++ 中迭代 emtpy 向量时会抛出运行时错误
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 程序在 Visual Studio 中停止运行时终止
- 调用 java 的回调() 时应用程序崩溃.由于 detatchThread 而获得运行时错误
- 在运行时使用枚举器值作为模板函数的模板参数的元程序
- QT C++防止关闭应用程序时出现运行时错误
- 每次运行此 c++ 程序时如何获得不同的数字?
- 运行 libpng 应用程序时出现运行时错误
- 以管理员身份运行应用程序时,有没有办法获取非管理员用户名
- 为什么程序运行时我的第二个循环不执行?
- valgrind:当试图调试在Docker容器内运行的C++程序时,堆块lo/hi大小不匹配
- 我的fahrenheit-celcius程序会忽略我的if-else语句,并在每次运行该程序时将值更改为0
- 如何在运行时对程序创建的.sys文件设置文件版本
- 如何在 c++ 程序运行时隐藏控制台?
- 在Visual Studio上运行时程序速度变慢
- 在 Eclipse 中运行时C++程序的输入提示不出现
- 当我在开发C++中编译和运行时程序崩溃
- 未连接调试器运行时程序中断