我有一个1GB的二进制文件,基本上包含相同类型值的3D立方体。使用不同顺序([x,y,z]或[z x, y])保存这种立方体需要使用fseek和fwrite花费很长时间。但是其中一个软件包比我的程序快得多。有没有方法可以使文件写入速度比使用fseek/fwrite更快?
我有一个1GB的二进制文件,基本上包含相同类型值的3D立方体。使用不同顺序([x,y,z]或[z x, y])保存这种立方体需要使用fseek和fwrite花费很长时间。但是其中一个软件包比我的程序快得多。有没有方法可以使文件写入速度比使用fseek/fwrite更快?
void writeCubeZYX( int* cubeXYZ, int sizeOfCubeXYZ, FILE* file )
{
int* cubeZYX = malloc( sizeOfCubeXYZ );
// all that monkey business you're doing with fseek is done inside this
// function copying memory to memory. No file IO operations in here.
transformCubeXYZ_to_ZYX( cubeXYZ, cubeZYX, sizeOfCubeXYZ );
// one big fat very fast fwrite. Optimal use of file io cache.
fwrite( file, cubeZYX, 1, sizeOfCubeXYZ );
free( cubeZYX ); // quiet pedantry.
}
@edit2:
假设您无法将所有内容都转换为内存中,则可以将其转换为平面,一次写出一个平面 - 按文件顺序 - 即不使用fseek。
因此,假设一个[XYZ]立方体在内存中被布置为一系列Z [XY]矩阵。也就是说,您的立方体的[XY]平面在内存中是连续的。并且您想要以[ZYX]的形式写出。因此在文件中,您要写出一系列X [ZY]矩阵。每个[ZY]在文件中是连续的。
因此,您可以像这样操作:
void writeCubeZYX( int* cubeXYZ, int x, int y, int z, FILE* file )
{
int sizeOfPlaneZY = sizeof( int ) * y * z;
int* planeZY = malloc( sizeOfPlaneZY );
for ( int i = 0; i < X; i++ )
{
// all that monkey business you're doing with fseek is done inside this
// function extracting one ZY plane at a time. No file IO operations in here.
extractZYPlane_form_CubeXYZ( cubeXYZ, planeZY, i );
// in X big fat very fast fwrites. Near optimal use of file io cache.
fwrite( file, planeZY, 1, sizeOfPlaneZY );
}
free( planeZY ); // quiet pedantry.
}
mmap
不可用,不过可能有一些等效的方法。 - Basile Starynkevitch如果您不介意将磁盘上的文件作为压缩文件,则在写入时进行压缩可能会更快。这样做可以加快速度,因为瓶颈通常是将字节写入磁盘,通过在写入时进行压缩,可以减少需要写入的字节数。
当然,这取决于您的数据是否适合压缩。在c++中压缩输出的一种选择是gzip。例如:如何读取/写入gzipped文件?
但在您的情况下,这可能不适用——从您的问题中不清楚您何时/为什么进行fseek。您预期的写入模式是什么?
fwrite
。也许使用write
可以节省一两微秒的时间,但是你无法从“慢”变成“快得多”。然而,我肯定会避免使用fseek
。 - Sergey Kalinichenko