MATLAB fwrite 开销

MATLAB fwrite overhead

我有一个二进制逻辑数据,我想将其保存到一个文件中,尽可能少 space。当我检查来自 MATLAB workspace 的数据大小时,它显示 103 kb,但是当我使用 fwrite ubit1 保存它时,它扩展到 105 kb?我该怎么做才能尽可能少地保存它?space?

Matlab 中的函数 fwrite 没有添加任何开销(或者您可能指的是元数据)。该函数与 "low level" 一样,在给定的机器上,它会给出与 CC++ 和更多语言中等效的低级函数相似的结果。

要访问磁盘,它们都将依赖于更底层的功能,由您的磁盘和操作系统的 filesystem 驱动。因此,在不同的磁盘、文件系统和 OS 之间,您可能会观察到最终结果的细微差别,但在给定的系统 (disk/FS/OS) 上,Matlab fwrite 与所有其他语言都相似,并且没有 "overhead".


现在数据大小与文件大小与磁盘大小的关系:

考虑以下片段:

nbits = 376 ;
A = true( nbits , 1 ) ;

fid = fopen( 'testsize.bin' , 'w' ) ;
fwrite( fid , A , 'ubit1' ) ;
fclose(fid) ;

这将创建一个 376 逻辑数组,然后将它们以 ubit1 格式写入磁盘。

在我们查看文件之前,请注意,正如 Horchler 评论中提到的,Matlab 在内存中仍然为每个逻辑(布尔值)使用一个完整的字节(8 位)。

>> whos A
  Name        Size            Bytes  Class      Attributes
  A         376x1               376  logical

但这不是问题,因为当 fwrite 将写入磁盘时,格式 ubit1 将告诉它仅使用(单个)有效位,因此正如 Horchler 评论的那样,文件将恰好是内存中变量大小的 1/8...

还是会 ??

如果我只是快速查看我的文件资源管理器,哎哟:

(这都是在PC上完成的,windows8、NTFS文件系统。)

1KB,naaaah,这只是因为它不是为显示小于该尺寸而设计的,它只是四舍五入。(unix/linux 用户可能会获得更好的显示效果,但嘿我在 windows 我必须处理它)。

为了获得更好的信息,我必须查询更多的细节,所以一旦我访问文件的属性,我得到:

pfeeew。 47 字节。听起来不错。让我们看看 376/8=47,是的,太完美了!

请注意 "size on disk" 高达 4KB。为什么你需要这么多 space 来存储我可怜的 47 字节?好吧,这与磁盘上文件系统的 "default allocation" 大小有关,例如,这是 fwrite 无能为力的事情之一。它仅由 OS/file 系统管理。

现在虽然浪费了很多磁盘,但我还是设法得到了信息,我的文件实际上只有47字节。那么成功? ...还没有。

我在开始时几乎是随机选择 376 位,还因为它是 8 的完美倍数。现在让我们尝试 运行 与上面完全相同的代码,除了我们将从以下内容开始:

nbits = 377 ;

代码 运行 没问题。该文件在资源管理器中仍显示为 1KB,但我们知道它是错误的,属性 现在显示:

377/8 = 47.125,不是48,探险家又是"rounded"。不!

文件大小实际上是48字节(不是少了一点也不是多了一点)。 (但是文件里面有用的信息只占47字节1位,后7位未定(或者挂'0'可能但不确定)。

幕后发生的事情是 fwrite 正在聚合我的位以按 8 个一组写入,构建一个完整的字节,然后只将完整的字节写入磁盘(有时甚至更大的组)。它在幕后完成了所有这些工作,但它必须这样做,因为文件系统(又是他)不会让他处理磁盘上的单个位。文件系统期望至少一个字节(或更多)的数据包。因此,当到达要写入的最后一位时,fwrite 必须在告诉文件系统将其写入磁盘之前用其他 7 位填充它。

我不是所有类型文件系统的专家,但我强烈怀疑许多文件系统是否允许您处理单个位,因此您应该期望的最小舍入将始终至少是一个字节......如果不多了。

总结

fwrite 不会引入开销,或者只会引入硬件和文件系统强制这样做的开销(在这种情况下,任何其他函数都无法做得更好)。