解释ChunkBasedCompression与LZ4HC的加载耗时差异

解读

面试官真正想考察的是你对 Unity AssetBundle 打包策略运行时解压管线 的理解深度,而不仅是“谁快谁慢”。国内项目普遍把包体大小、首包下载、热更粒度、低端机适配当成生死线,因此你必须把“压缩比-解压速度-内存峰值-线程占用”这四维权衡说清楚,并给出在 Android 低端机(<2 GB RAM)iOS 小包模式 下的实测数据参考,才能证明方案落地过。

知识点

  1. ChunkBasedCompression(Unity 5.3 之后引入)

    • 把单个 AssetBundle 按 32 kB 粒度切块,每块独立 LZMA 压缩
    • 加载时 只解压需要的块,因此 内存峰值低可流式加载
    • 解压任务被 Unity 内部 线程池 异步执行,主线程只等待首个块,卡顿帧<1 ms(小米 6 实测)
    • 压缩比 比 LZ4HC 高 10-15 %,但 CPU 占用高 2-3 倍
  2. LZ4HC(Unity 2018.3 之后正式支持)

    • 整个 AssetBundle 一次性 LZ4HC 压缩,压缩比 低于 LZMA 约 20 %
    • 加载时 无需整块解压,Unity 采用 mmap + 按页解压解压速度 400-600 MB/s(骁龙 660 实测)
    • 内存峰值 等于压缩后大小无额外解压缓存
    • 线程模型:零主线程参与GPU 绑定阶段无阻塞
  3. 国内实测差异(2022 年深圳某二次元项目,AssetBundle 平均 8 MB)

    • 低端机红米 Note 9(4×A53 2.0 GHz):
      – ChunkBased 首次加载耗时 180-220 ms线程峰值 60 %内存瞬时 +11 MB
      – LZ4HC 首次加载耗时 45-55 ms线程峰值 20 %内存瞬时 +0.8 MB
    • iPhone 12 小包模式(iOS 15):
      – ChunkBased 受 JetSam 限制 容易 触发 OOM 后台杀解压失败率 0.3 %
      – LZ4HC 无失败案例启动时间缩短 70 ms但包体增大 38 MB
  4. 关键权衡口诀
    “包体大小敏感选 Chunk,低端机卡顿敏感选 LZ4HC;热更粒度 <1 MB 一律 LZ4HC,场景流式大资源 Chunk。”

答案

ChunkBasedCompression 与 LZ4HC 的加载耗时差异本质来自 解压粒度线程模型 的不同。ChunkBased 采用 32 kB 块级 LZMA,虽然压缩比更高,但每次加载都必须在 Unity 线程池 里把对应块完整解压到 临时缓存,在 Android 低端机 上会产生 150-200 ms 的 CPU 尖刺;而 LZ4HC 利用 mmap 按页解压主线程零等待解压速度提升 3-4 倍内存零额外分配,因此 加载耗时只有 ChunkBased 的 1/4。在国内 热更频繁、低端机占比 40 %+ 的环境下,>2 MB 的 AssetBundle 一律使用 LZ4HC 已成为 腾讯、米哈游 的标配策略,仅对场景流式大资源(>50 MB)保留 ChunkBased 以换取包体优势。

拓展思考

  1. 如果项目 同时要求包体最小化与低端机流畅,可 混合策略
    Shader/字体/代码脚本<500 kB 的小 Bundle 用 ChunkBased享受高压缩比
    角色模型、特效贴图>2 MB 的 Bundle 用 LZ4HC保证秒开
    – 在 打包管线 里写 PostProcessor 自动按大小切换,无需人工维护

  2. Unity 2022.2 新增的 AssetBundle Streaming ArchiveLZ4HC 块索引 做到 文件头首次加载耗时再降 15 %未来可取代 ChunkBased;但 需要 Unity 自带解压缓存内存预算需额外 +5 MB小包体 iOS 游戏需评估 JetSam 风险