C++ 如何加速我的.bmp课程?

C++ 如何加速我的.bmp课程?,c++,file,file-io,fstream,ofstream,C++,File,File Io,Fstream,Ofstream,向你们大家问好:) 几天前,我终于成功地创建了一个功能C++类来制作BMP图像。即使它是功能性的(还没有错误),它在速度方面也没有效率(在我看来)。我做了一些测试,看看写不同大小的图像需要多少时间,结果如下: Image Dimensions Time taken(in seconds) Comparison to the 1000x1000 image 10x100 0.0491 x 1000 = 49.1 secon

向你们大家问好:)

几天前,我终于成功地创建了一个功能C++类来制作BMP图像。即使它是功能性的(还没有错误),它在速度方面也没有效率(在我看来)。我做了一些测试,看看写不同大小的图像需要多少时间,结果如下:

Image Dimensions   Time taken(in seconds)     Comparison to the 1000x1000 image
10x100             0.0491                     x 1000 = 49.1 seconds
100x100            0.2471                     x 100  = 24.7 seconds
100x1000           2.3276                     x 10   = 23.3 seconds
1000x1000          22.515                     x 1    = 22.5 seconds
1000x10000         224.76                     \ 10   = 22.4 seconds
例如,10x100图像有1000个像素(每个像素有一个ARGB通道[32位或4个字节])加上54个字节作为标头,写入4054个字节(字符)需要0.05秒

我觉得这太慢了,因为我的电脑可以在一两秒钟内复制一个约85MB的文件。我正在使用fstream进行磁盘写入,非常感谢您为加快课堂进度所做的任何帮助。谢谢你

我的类称为SimpleBP,这里是(我只放了相关函数):

#包括
类SimpleBMP{
结构像素{
无符号字符A、R、G、B;
}*像素阵列;
未签名字符*BMPHEADER,*BMPINFOHEADER;
std::字符串数据;
无符号整数大小\u的\u BMP,大小\u的\u像素数组;
int BMP_宽度,BMP_高度;
公众:
void SetPixel(int列、int行、无符号字符A、无符号字符R、无符号字符G、无符号字符B){
像素数组[(行*BMP_宽度)+列].A=A;
像素数组[(行*BMP_宽度)+列].R=R;
像素数组[(行*BMP_宽度)+列].G=G;
像素数组[(行*BMP_宽度)+列].B=B;
};
bool MakeImage(标准::字符串名称){
名称。追加(“.bmp”);
std::of流OffFile(名称,std::ios::out | std::ios::binary);
如果(OffFile.is_open()){
DATA.clear();
用于(内部温度=0;温度<14;温度++){
BMPHEADER[temp]=0x00;
};
BMPHEADER[0]=“B”;
BMPHEADER[1]=“M”;
BMPHEADER[2]=BMP的大小;
BMPHEADER[3]=(BMP>>8的大小);
BMPHEADER[4]=(BMP>>16的大小);
BMPHEADER[5]=(BMP>>24的大小);
BMPHEADER[10]=0x36;
对于(内部温度=0;温度<40;温度++){
BMPINFOHEADER[temp]=0x00;
};
BMPINFOHEADER[0]=0x28;
对于(int-temp=0;temp<4;temp++){
BMPINFOHEADER[temp+4]=(BMP_Width>>(temp*8));
};
对于(int-temp=0;temp<4;temp++){
BMPINFOHEADER[temp+8]=(BMP_高度>>(temp*8));
};  
BMPINFOHEADER[12]=0x01;
BMPINFOHEADER[14]=0x20;
对于(int-temp=0;temp<4;temp++){
BMPINFOHEADER[temp+20]=(像素阵列的大小>>(temp*8));
};
BMPINFOHEADER[24]=0x13;
BMPINFOHEADER[25]=0x0b;
BMPINFOHEADER[28]=0x13;
BMPINFOHEADER[29]=0x0b;
用于(内部温度=0;温度<14;温度++){
数据。推回(BMPHEADER[temp]);
};
对于(内部温度=0;温度<40;温度++){
数据。推回(BMPINFOHEADER[temp]);
};
对于(int-temp=0;temp<(像素阵列的大小/4);temp++){
DATA.push_back(像素数组[temp].B);
DATA.push_back(像素数组[temp].G);
DATA.push_back(像素数组[temp].R);
DATA.push_back(像素数组[temp].A);
};  
write(DATA.c_str(),大小为\u BMP);
OffFile.close();
返回true;
}
其他的
返回false;
};

})

如果您知道自己在一台小型endian机器上,您可以完全跳过数据的重新打包,直接存储pixelarray数据

OffFile.Write((char *)&PixelArray, Size_Of_BMP);
它可能没有那么便携,但肯定会加快保存到文件的速度

(你可以喝一杯

#ifdef LITTLE_ENDIAN
struct PIXEL{
    unsigned char A, R, G, B;
};
#else
struct PIXEL{
    unsigned char B, G, R, A;
};
#endif    

PIXEL *PixelArray;

在声明中。

在运行测试时,您应该在发布模式下编译项目。大多数环境中的调试模式都会引入额外的检查和代码。链接的调试库还可以包含额外的检查,例如边界检查和迭代器的验证,这些检查在发布模式下不存在。所有这些都会引入pe不在释放模式中的格式命中


您还可以应用其他优化,例如在加载数据之前在
数据中保留内存。这将减少扩展缓冲区时需要创建的副本数。虽然性能增益可能不显著,但肯定会有所帮助。我建议通过探查器运行代码,以查看所有的瓶颈都是可用的,并进行相应的优化。

一件事是调用
DATA.reserve()
为数据预分配正确的空间量。这将消除大量不必要的复制。还要确保您是在发布模式下编译,而不是在调试模式下编译。您是否确定时间为秒,并且只配置写函数。我认为在磁盘上复制1000x1000 RGBA8映像不会花费22秒。您的code并没有那么糟糕,优化不必要的缓冲区副本并不能解决22秒的问题。这在所有情况下都不是必需的,但你应该选择“++temp”而不是“temp++”。@a.lasram.reserve()使数据的速度提高了2.2%左右。我也认为这太长了,但这是程序所做的一切。SetPixel()我做的循环花费了大约0.3秒。剩下的是.MakeImage(),最后程序结束了。我将尝试并继续改进。确保您的检测系统提供了特定于“toOffFile.write”的详细信息是的,但我打算将其与噪声功能结合起来,并且必须使其便于终端用户使用big-endian机器。尽管知道这是可能的是件好事。
#ifdef LITTLE_ENDIAN
struct PIXEL{
    unsigned char A, R, G, B;
};
#else
struct PIXEL{
    unsigned char B, G, R, A;
};
#endif    

PIXEL *PixelArray;