我想写一个包含1个整数的表,然后是二进制格式的3个双精度表。 当然我可以做一个for循环
for i=1:sz
fwrite(fid, integ(i), 'int');
fwrite(fid, doubl(i,:), 'double');
end
但是对于具有几百万个条目的数组来说这是非常慢的。 处理此问题的最有效方法是什么(无需编写.mex)?
不幸的是我必须保留这个[int32 float64 float64 float64]格式,因为这是程序使用的文件格式规范。
答案 0 :(得分:1)
修改强>
所以最后做到这一点并且尊重变量的确切顺序和类型的最快方法是将nx3 double
的表转换为(2xn)x3 int32
的数组,重新整形并连接数组然后一次性写入所有内容。
outfile4 = 'test1.bin' ;
tic4 = tic ;
% // reshape everything
table2write = int32(zeros(2*nCol+1,nPt)) ;
table2write(1,:) = integ.' ; %'
for k=1:nCol
ixLine = (k-1)*2+2 ;
table2write( ixLine:ixLine+1 , : ) = reshape( typecast(doubl(:,k),'int32') , 2 , [] ) ;
end
% // write
fid = fopen( outfile4 , 'w' ) ;
count = fwrite(fid , table2write , 'int32' ) ;
fclose( fid ) ;
elapsed4 = toc(tic4)
结果如下:
elapsed4 =
0.794346687070910
阅读下面的内容,了解测试变量的定义和稍快的方法,但会使数组变形
原始回答:
如果你有能力重新组织你的文件,你可以获得大量的时间。
考虑以下示例:
outfile1 = 'E:\TEMP\Z_ToDelete\test1.bin' ;
outfile2 = 'E:\TEMP\Z_ToDelete\test2.bin' ;
nPt = 0.5e6 ;
integ = int32( randi(32000,nPt,1) ) ;
doubl = rand(nPt,3) ;
%% // Write to file with mixed precision
tic1 = tic ;
fid = fopen( outfile1 , 'w' ) ;
for k = 1:nPt
fwrite(fid, integ(k), 'int');
fwrite(fid, doubl(k,:), 'double');
end
fclose( fid ) ;
elapsed1 = toc(tic1)
%% // write to file sequentially
tic2 = tic ;
fid = fopen( outfile2 , 'w' ) ;
fwrite(fid, integ, 'int');
fwrite(fid, doubl, 'double');
fclose( fid ) ;
elapsed2 = toc(tic2)
在我的系统上,此输出:
elapsed1 =
19.7780466501241
elapsed2 =
0.0309073378234669
因此,让Matlab处理完整数组的编写,一次一个精度比逐行指定要写的内容更有效。
缺点是从您保存的文件中读取一条记录可能会稍微复杂一些,但您可以轻松编写一个函数,对于给定的索引将会读取integer
,跳过其余部分然后阅读3x doubles
。
如果您真的无法承担多路复用/多路分解数据的费用,那么您可以考虑将int
转换为double
并编写完整数组:
tic3 = tic ;
A = [double(integ) doubl] ;
fid = fopen( outfile2 , 'w' ) ;
fwrite(fid, A, 'double');
fclose( fid ) ;
elapsed3 = toc(tic3)
这仍然比最初的"混合精度"更快。溶液
elapsed3 =
0.483094789081886
在读取它们时,将它们转换为整数将花费更少的时间,而不是用于编写混合精度值。这种方法的唯一缺点是文件大小略有增加(约14%)。