【问题标题】:Disk cache vs Recreating the image磁盘缓存与重新创建映像
【发布时间】:2023-03-09 12:35:02
【问题描述】:

我目前有一个应用程序,我可以在其中进行大量图像处理。我基本上拍摄 320x320( 或 Retina 上 640x640)的图像,然后将其缩小到 128x128( 或 Retina 上 256x256),然后将其四角修圆并应用光泽高光.一切都是使用 Core Graphics 绘图完成的。

在任何时候都可能有大约 600 个图像需要此处理,因此我在应用程序启动时使用后台线程执行大约 40 个并将它们缓存到 FIFO 队列中。当不在缓存中的图像需要处理时,我会这样做并将其添加到缓存的末尾,丢弃第一个缓存的图像。如果再次需要第一个图像,它会经历相同的过程。

我想知道的是,将丢弃的图像保存到磁盘而不是在下次需要它们时从头开始重新创建它们是否更有意义并且最终更有效,因为我可以改为读取它们从磁盘。

这些图像也使用CALayer 显示,因此在设置图层内容时可能会因为从UIImage 转换为CGImage 而产生开销。如果我将它们存储在磁盘上,我相信它们可以直接作为CGImage 读取?

我们真诚欢迎任何有关提高此流程效率的想法和意见。

【问题讨论】:

  • 请注意,解压缩图像需要的时间比从磁盘读取图像要长cocoanetics.com/2011/10/avoiding-image-decompression-sickness 我猜你必须对每个部分进行计时(读取、解压缩、缩放+舍入+光泽),看看会发生什么。
  • 我会在保存之前缩放+圆形+光泽,所以我唯一需要了解的是解压缩成本。图像不能未压缩存储吗?比如仅仅存储他们的数据?

标签: iphone objective-c ios caching core-graphics


【解决方案1】:

我个人的选择是使用磁盘缓存。

但是,您说“哪个更高效”——您是什么意思?

  • 如果您的意思是更快,那么磁盘缓存可能会胜出。
  • 如果您的意思是更节省空间,那么重新创建它们会胜出。
  • 如果您的意思是较低的内存使用量,那么这完全取决于您的实现!

你必须尝试一下,看看:)

但是,磁盘解决方案的优势在于,您的应用第二次启动时,它已经完成了处理,因此启动速度会更快。这就是我使用磁盘的原因。

【讨论】:

  • 高效,我的意思是更快。我每次只在内存中保存大约 40 张图像,因此内存使用并不是真正的问题。图像可能会发生变化,因为它们是用户 iPod 音乐库中的艺术品,因此每次同步后都需要将它们缓存到磁盘。您认为使用CGImageCreateWithPNGDataProvider 之类的方法从磁盘读取数据并将图层内容设置为结果而不是使用UIImage 和方便的方法会更快吗?
  • 我认为 UIImage 会以尽可能少的开销编写(它甚至可能在幕后使用 CALayer 的东西!)我个人会使用 UIImage 的便利(除非它开始成为问题。然后你应该做一些基准测试,看看哪个更快,以及更复杂的代码是否值得)。音乐库中的艺术作品实际变化的频率如何?我敢打赌,这不会那么频繁 - 如果你追求速度,那么一定要使用磁盘。
  • 改变的并不是艺术品。每个MPMediaItem 都有一个id,它只在iPod 库同步(有变化的地方,例如添加或删除专辑)之间保持不变。将磁盘上缓存的封面与专辑相关联的唯一方法是使用该 ID,因此每次同步并且项目 ID 更改时,您都需要重新缓存整个库。
  • 臭虫,这很烦人 :( 你可以为缓存的图像使用非 ID 键?或者你别无选择;清除缓存并在后台线程上按需重新创建图像。虽然我'会假设应用程序运行的次数应该高于清除 ID 的同步次数,因此您仍然可以获得性能优势。
【解决方案2】:

根据我的经验,保存然后从磁盘读取会更快。我一遍又一遍地做这件事,而不是保存和阅读,我有一些记忆警告。但是,唯一确定的是尝试。我使用了大约 1000 张图像,所以在我的情况下使用磁盘是有意义的。

【讨论】:

  • 在开发过程中,我最多只能处理大约 600 张图像,但一旦应用发布,这可能会增加。我只在内存中保存了大约 40 张图像,在 iPhone 4 上大约需要 10-12mb,在 3GS 上大约需要 2.5mb。
  • 尝试尽可能多地持有,例如,即使它在您的上下文中没有意义,也总是试图推动事物(墨菲定律...:P)。因此,如果您目前需要最多 600 个,请尝试保持 800 个,以查看您的应用程序的行为方式。检查日志以获取内存警告。
  • 在 Retina 上,图像平均为 250k (256x256x4),因此在内存中保存 600 个图像需要大约 150mb,这在 iPhone 上是不可能的。这就是为什么我将其保持在 10mb 左右或更低的原因。
  • 内存中有 150 mb...不要忘记...在 90 mbs 的标记处,我的应用程序收到内存警告并正在关闭。使用 Instruments 中的 Activity Monitor 对其进行测试。
  • 很抱歉,我似乎没有理解您的意思。如果您的应用程序在 90mb 左右被关闭,我怎么能期望在内存中保持 150mb 以上?
【解决方案3】:

试试 github 的 libs 也不错,它可以从 Internet 下载和缓存 UIImage/NSData。

它可以通过 SDWebImage(https://github.com/rs/SDWebImage) 或 APSmartStorage (https://github.com/Alterplay/APSmartStorage)。

APSmartStorage 有助于从网络获取数据,并以智能可配置的方式自动将数据缓存在磁盘或内存中。应该够好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2017-11-19
    • 2019-03-14
    • 2010-09-15
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    相关资源
    最近更新 更多