【问题标题】:Flat or nested directory structure for an image cache?图像缓存的平面或嵌套目录结构?
【发布时间】:2011-06-16 12:13:03
【问题描述】:

我的 Mac 应用程序保留了一组对象(使用 Core Data),每个对象都有一个封面图像,并且我在创建时为其分配了一个 UUID。我最初将封面图像作为一个字段存储在我的 Core Data 存储中,但最近开始将它们存储在文件系统的磁盘上。

最初,我将封面存储在一个平面目录中,使用 UUID 命名文件,如下所示。这给了我 O(1) 的获取时间,因为我确切地知道在哪里看。

...
/.../Covers/3B723A52-C228-4C5F-A71C-3169EBA33677.jpg
/.../Covers/6BEC2FC4-B9DA-4E28-8A58-387BC6FF8E06.jpg
...

不过,我查看了其他应用程序处理此任务的方式,并注意到一个多级方案,如下所示(例如)。这仍然可以在 O(1) 时间内实现。

...
/.../Covers/A/B/3B723A52-C228-4C5F-A71C-3169EBA33677.jpg
/.../Covers/C/D/6BEC2FC4-B9DA-4E28-8A58-387BC6FF8E06.jpg
...

这样做的原因可能是什么? OS X 是否限制目录中的文件数?从磁盘中检索它们是否以某种方式更快?这会使用于计算文件名的代码更加复杂,所以我想看看是否有充分的理由这样做。

【问题讨论】:

    标签: macos file caching filesystems io


    【解决方案1】:

    在某些文件系统上(我也相信 HFS+),在同一个目录中有太多文件会导致性能问题。

    我曾经在一家 ISP 工作,他们会使用多目录方案来分解主目录(他们有 90k 多个)。您可以使用 UUID 的前两个字符,然后是后两个字符来对目录进行分区,例如:

    /.../Covers/3B/72/3B723A52-C228-4C5F-A71C-3169EBA33677.jpg
    /.../Covers/6B/EC/6BEC2FC4-B9DA-4E28-8A58-387BC6FF8E06.jpg
    

    这样您就不需要计算任何额外的字符或代码,只需使用已有的字符或代码将其分解即可。由于您的 UUID 每次都会不同,这应该足够了。

    【讨论】:

    • 谢谢,我一直在考虑这些问题。我将 UUID 设为 NSMutableString,然后在前两个字符和后两个字符之后插入 /,所以现在我的文件名也缩短了 4 个字符。
    • 不过,将其分解得过多会受到惩罚吗?使用您的 2 个 2 个十六进制数字目录的方案,每个目录意味着创建最多 256^2 个目录,这意味着(假设均匀分布)每个文件实际上都有自己的目录。
    • 这取决于您打算存储多少个文件,但是,您可以从 1 位开始,然后如果太多,则使用第二位创建子目录,依此类推。
    【解决方案2】:

    主要原因是后一种方式,正如您所提到的,磁盘检索更快,因为您的目录更小(因此 FS 将在较小的表中查找文件是否存在)。

    【讨论】:

    • 所以,要明确一点,从内容更多的目录中读取文件需要更长的时间?
    • 没有。操作系统需要更长的时间来确定该目录中是否存在文件。一旦你得到文件句柄,读/写时间应该是一样的。
    【解决方案3】:

    正如其他人提到的,在某些文件系统上,操作系统打开文件需要更长的时间,因为一个包含许多文件的目录比几个短目录的读取时间更长。

    但是,您应该针对您的特定文件系统和特定使用场景执行测量。我在 Windows XP 上为 NTFS 执行此操作,并惊讶地发现平面目录在各种测试中的性能都优于分层结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多