【问题标题】:NSURL Bookmarks: A Faster Alternative?NSURL 书签:更快的选择?
【发布时间】:2016-03-23 18:07:15
【问题描述】:

上下文

我的应用程序模型是一个对象树,其中每个对象代表磁盘上给定起始文件夹下的一个文件系统项(文件夹或文件)。

定期地,我从上到下递归地遍历这棵树,以便将它“同步”到文件系统的实际状态。也就是说,我访问模型中的每个对象并验证它所代表的文件/文件夹是否仍然存在于磁盘上的同一位置。

如果文件/文件夹已移动,我使用NSURL 书签来确定文件/文件夹的新位置,以便更新模型的状态。 (我在第一次创建模型对象时创建了一个NSURL 书签,然后将书签数据存储为对象的一个​​属性,以便我以后可以解决它。)


问题

NSURL 书签性能不够。我的模型图有 20,000 个嵌套对象并不少见。每个人都有一个书签。这是我在分析性能时看到的:

recursivelyValidateExistingChildItemsOfParentItem:... 方法是遍历我的模型树的方法。所涉及的 90% 时间只是解决书签(如果它们过时,则按照 Apple 文档中的说明重新创建它们)。

因此,该应用程序需要将近 2 分钟才能完成步行。所以,我需要一个更快的替代 NSURL 书签。


我的考虑

  1. 扩展文件属性。我可以为磁盘上的每个文件添加一个 UUID 属性。我可以遍历起始文件夹下的实际文件系统,而不是遍历我的模型图。当我找到一个新文件时,我可以查看它是否具有 UUID 扩展属性。如果是这样,我可以在我的模型图中搜索具有该 UUID 的对象以处理移动/重定位的文件。这里的问题是很多东西破坏了扩展文件的属性——它们不能保证会一直存在。

  2. BDAliasNDAlias。在迁移到 NSURL 书签之前,我曾经使用过 BDAlias,但这并不是特别高效。


底线

我需要一个更快的替代NSURL 的书签。但是我仍然需要能够在我的应用程序启动时跟踪文件,所以简单地保持文件描述符打开或使用文件 ID 是行不通的。

我不在乎我必须达到多低的水平;我只需要表现。谢谢!

【问题讨论】:

  • 定期地,我从上到下递归地遍历这棵树,以便将其“同步”到文件系统的实际状态。 这不是 NSURL 书签的性能,可能是您问题的很大一部分。您可能无法避免在每次启动时验证大型目录结构,但此后您不需要扫描整个内容 - 相反,使用FSEvents API 来通知文件系统更改,这样您就可以只扫描您需要的内容到,当你需要的时候。
  • 谢谢瑞克斯特。你可以假设 FSEvents 和我亲密相识。我对该 API 的各个方面都非常熟悉。非常适合学习,“文件夹 X 中的内容已更改”。知道以前在 X 中的东西去了哪里并不是很好——这正是我需要解决的问题。即使在文件级粒度模式下,FSEvents 也不是合适的解决方案。而且,正如您所指出的,它对发布没有帮助。
  • 另外:我不是故意不屑一顾的。有很好的理由需要我的全面扫描方法。 FSEvents 可以删除事件,当 FSEvents 不跟踪时用户可能会更改文件系统(例如在另一台 Mac 上的可移动 USB 密钥上),某些文件夹实际上是通过 MacFuse 安装的远程服务器,它不会处理相同的事件等。为了简洁起见,我把这些东西放在外面。我希望我不必进行全面扫描,但这是处理所有边缘情况的唯一可靠方法。

标签: objective-c macos performance cocoa nsurl


【解决方案1】:

我知道这个问题很老了。但这是我的答案:

我只使用解析书签作为后备。我将文件路径和 URL 书签数据都保存在我的模型中。当我想打开文件时,首先我检查文件是否仍然存在于先前已知的位置。如果没有,我会尝试解析 url 的书签数据。这会将对URL.init(resolvingBookmarkData) 的调用范围缩小到项目的有限子集。然后我会在解析书签后使用新路径更新模型以保持性能合理。

如果您需要确保使用完全相同的文件,您可以检查文件的日期、大小或特定的 EA 作为额外的测量值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多