为什么一个包含很少数据的 Python shelf 文件在 macOS 上这么大?

Why is a Python shelf file containing very little data so large on macOS?

我只是按照书中给出的示例来说明 macOS High Sierra 上的 Python shelve 模块。

如下所示,只有两个小的短字符串元组存储在一个 shelf 中。正如您在最后一行中看到的那样,生成的文件大小为 16 兆字节。

只有当我在通过 Homebrew(3.6.4 或 2.7.14)安装 Python 版本的 macOS High Sierra 上尝试示例时,结果文件才会变得那么大。如果我 运行 它在 Linux 主机上或使用预安装的 Python 版本 (2.7.10) 或通过 macOS 中的官方安装程序安装 Python 3.6.4 ,生成的 addresses 文件只有几千字节大,正如其他人在评论中所报告的那样(谢谢!)。

 ~/tmp> rm addresses
 ~/tmp> python3
Python 3.6.4 (default, Jan  6 2018, 18:43:09)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
[...]
>>> import shelve
>>> book = shelve.open("addresses")
>>> book['flintstone'] = ('fred', '555-1234', '1233 Bedrock Place')
>>> book['rubble'] = ('barney', '555-4321', '1235 Bedrock Place')
>>> book.close()
>>>
 ~/tmp> ll
total 32768
-rw-r--r--  1 moritz  staff    16M Jan 24 13:05 addresses

我可以确认此行为是由 gdbm 1.14 引入的,gdbm 是 shelve 用来访问数据库文件的库。

对于 change 2e8a5e0,gdbm 将尝试扩展文件大小以匹配 next_block_sizenext_block_size4 * block_size计算得出, 这是底层文件系统 obtained by stat.st_blksize returned by stat(2) 的最佳 I/O 块大小。在我的 macOS 10.13.3 上,SSD 卷上的 APFS 文件,stat.st_blksize 是 4194304 字节,next_block_size 是 16777216 字节,因此 init db 文件大小是 16MB。

ps: 我检查了手头硬盘卷上的 HFS+ fs,st_blksize 值为 4096 字节。