不改一行代码,就极大提高对本地图片加载速度(对 Asset 的探讨)

2017年8月4日更新

根据这个 Session Optimizing I/O for Performance and Battery Life 的描述,使用 Asset 还有对启动优化的好处。

Asset Catalogs

10%的速度提升

如果你是被标题吸引进来的

可以直接跳到最后看结论,接下来是对 Asset 为什么能加快对本地图片加载速度的探讨。

为什么探讨 Asset 这个东西

由于项目中在刚启动的瞬间使用 "-[UIImage imageNamed:]" 会很慢,所以就打算探讨 "-[UIImage imageNamed:]" 的实现,但是过程中发现了使用 Asset 对于图片的加载有极大的提升,就去探讨 Asset 了。

使用 Time Profiler 探索实现

在使用 Time Profiler 调试 "-[UIImage imageNamed:]" 时候,发现它实际是调用 "-[UIImage imageNamed:inBundle:compatibleWithTraitCollection:]" 的,这时候萌发了一个想法是会不会根据指定 Bundle 的范围会加快加载图片的速度(理由是文件夹小了,减少索引次数)。

实验后发现,果然如此。把图片分散到指定 bundle 后的速度大大提升了。

这时候,有同事提示我使用 Asset 会不会加快,因为 WWDC 有提到过。所以我就去看了这集 Session,发现它是这样描述的。

发现使用 Asset 后速度也大大提升。到此为止就产生了探讨 Asset 这个东西的需求了。

符号断点跟踪步骤

这里就用两个图片来简单描述 "-[UIImage imageNamed:]" 发生了什么?

左图 Aseet/ 右图 Folder
上图 Aseet/ 下图 Folder

使用 Asset 底层是使用一个叫 _UIAssetManager 的类去存取图片,而使用 Folder 则是走 imageIO。而且即使你是用 Folder 也会先判断 Asset 中没有这张图片才去走 imageIO 。

这里就不展开说,具体可以根据图中的函数名下符号断点跟踪。(建议使用 chisel 来看各个类的成员变量)

缓存结构和索引的不同

使用 Asset 的缓存结构是: CUIStructuredThemeStore(https://github.com/billinghamj/iPhone6-iOS8-RuntimeHeaders/blob/master/PrivateFrameworks/CoreUI.framework/CUIStructuredThemeStore.h)

// _cache
[
Hash(A.png) -> 缓存
Hash(B.png) -> 缓存
]

使用 Folder 的缓存结构是: CUIMutableStructuredThemeStore(https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/PrivateFrameworks/CoreUI.framework/CUIMutableStructuredThemeStore.h)

// nameIdentifierStore
[
A.png -> 1
B.png -> 2
]

// memoryStore
[
Hash_(1) -> 缓存
Hash_(2) -> 缓存
]

因为使用 Folder 去查找缓存,会先遍历 nameIdentifierStore 查找是否有缓存,没有就从 Folder 读取。在 Time Profiler 会有那么多的 "isEqualTo" 比较。

而使用 Asset 则是直接根据图片名称来直接 "objectForKey:" 取出缓存。

两者速度比较是: 前者 O(n)+O(1),后者 O(1)。
(至于为什么是O(n)? 因为我观察有O(n)这个行为,且 "isEqualTo" 的参数刚好字典 keys 和当前需要图片的名字。)

而且看出来建立这个缓存的时候,使用 Asset 会快一点(只需要一个字典就可以)。

文件 IO 的不同

假设都是读取 5 张图片

使用 Asset 的 IO 过程是:
open Asset -> read Asset -> close Asset

使用 Folder 的过程是:
open 1.png -> read 1.png -> close 1.png
open 2.png -> read 2.png -> close 2.png
open 3.png -> read 3.png -> close 3.png
open 4.png -> read 4.png -> close 4.png
open 5.png -> read 5.png -> close 5.png

可以看出这里 IO 次数少了(如果数量大的话,比较更加明显,Asset 一直是 1 次IO,而 Folder 会随读取文件的多少而递增),而且在 IO Usage 可以看出读取 Asset 的速度极快。

asset.car 到底是什么

asset.car 是编译后打包到项目里的文件。从目前的研究来看,asset.car 其实是将资源打包并建立索引的二进制文件,其头部包含资源在二进制对应的位置(类似 seekTable)。

小结

所以使用 Asset 的速度快的原因有以下几点:

  1. 缓存格式较优,从而建立和查找缓存的速度也会加快。
  2. 图片储存方式较优,查找图片位置更快,IO 也更快。

从 Folder 到 Asset,你需要做的只是转移图片资源(Xcode支持将Folder图片一键导入),并且不需要改任何代码就能使图片加载速度大大加快。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 在第13章“高效绘图”中,我们研究了和Core Graphics绘图相关的性能问题,以及如何修复。和绘图性能相关紧...
    雪_晟阅读 622评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,498评论 25 707
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,094评论 5 13
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,358评论 0 17