我有1GB的二进制文件,它基本上包含相同类型值的3D立方体。使用不同的顺序([x,y,z]或[z x,y])保存这种立方体需要花费很多时间来使用fseek和fwrite。但其中一个软件包比我的程序快得多。是否有任何方法使文件写入速度快于fseek / fwrite?
答案 0 :(得分:7)
你不应该在文件io操作的内部循环中使用fseek。为了使写入功能更快,它们会缓存写入。如果你到处寻找,你就会不停地吹着缓存。
在内存中进行所有转换 - 例如在内存中旋转多维数据集,然后在几个后续的fwrite调用中写入文件。
如果你无法在内存中完全转换数据,那么在内存中一次将一个平面组装成一个平面并写出每个平面。
@edit:
在你的情况下你根本不想使用fseek。甚至不是一个。
做这样的事情:
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:
好吧假设你无法在内存中将其全部转换然后在平面中进行转换并一次写出一个平面 - 按文件顺序 - 没有fseeks。
所以说[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.
}
答案 1 :(得分:1)
如果你正在做很多随机访问写作。我建议你使用mmap。 mmap将内存页面映射到您的文件,并由操作系统控制。类似于内存交换机制。
另一种方法是使用异步IO。它由GLIBC提供 http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html
它只是将数据放入内存中的队列中,然后创建另一个线程来管理IO。
答案 2 :(得分:0)
如果你不介意将磁盘上的文件作为压缩文件,那么在编写它时压缩它可能会更快。这会加快速度,因为瓶颈通常是将字节写入磁盘,并且在编写时通过压缩来减少需要写入的字节数。
这当然取决于您的数据是否适合压缩。在c ++中压缩输出的一个选项是gzip。例如:How do I read / write gzipped files?
但是在你的情况下,这可能不适用 - 从你的问题中不确切地知道你何时/为何要求你。你期望的写作模式是什么?