compare-cache-runs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Compare Cache Runs

对比缓存运行

Quick Start

快速开始

You'll typically receive two cache run identifiers. Follow these steps:
  1. Run
    tuist cache-run list --json
    to find cache runs on each branch.
  2. Run
    tuist cache-run show <id> --json
    for both base and head cache runs.
  3. Compare duration, status, and cache hit rates.
  4. Summarize cache changes with root cause analysis.
通常你会收到两个缓存运行标识符,请按照以下步骤操作:
  1. 运行
    tuist cache-run list --json
    查找各分支上的缓存运行记录。
  2. 分别对基准(base)和目标(head)缓存运行执行
    tuist cache-run show <id> --json
  3. 对比运行时长、状态和缓存命中率。
  4. 结合根本原因分析总结缓存变化情况。

Step 1: Resolve Cache Runs

步骤1:解析缓存运行记录

If base/head are cache run IDs or dashboard URLs

若基准/目标为缓存运行ID或仪表板URL

Fetch each directly:
bash
tuist cache-run show <base-id> --json
tuist cache-run show <head-id> --json
直接获取两者的详细信息:
bash
tuist cache-run show <base-id> --json
tuist cache-run show <head-id> --json

If base/head are branch names

若基准/目标为分支名称

List recent cache runs on each branch:
bash
tuist cache-run list --git-branch <base-branch> --json --page-size 1
tuist cache-run list --git-branch <head-branch> --json --page-size 1
Then fetch full details with
tuist cache-run show <id> --json
.
列出各分支上的近期缓存运行记录:
bash
tuist cache-run list --git-branch <base-branch> --json --page-size 1
tuist cache-run list --git-branch <head-branch> --json --page-size 1
随后使用
tuist cache-run show <id> --json
获取完整详情。

Defaults

默认规则

  • If no base is provided, use the project's default branch (usually
    main
    ).
  • If no head is provided, detect the current git branch.
  • 若未提供基准分支,将使用项目的默认分支(通常为
    main
    )。
  • 若未提供目标分支,将自动检测当前git分支。

Step 2: Compare Top-Level Metrics

步骤2:对比顶层指标

After fetching both cache runs, compare:
MetricWhat to check
duration
Flag if head is >10% slower
status
Flag if base succeeded but head failed
cacheable_targets
Note if target count changed
local_cache_target_hits
Compare local hit counts
remote_cache_target_hits
Compare remote hit counts
is_ci
Note if one is CI and the other local
Compute cache hit rates:
  • Base:
    (local_hits + remote_hits) / cacheable_targets * 100
  • Head: same formula
  • Delta:
    head_rate - base_rate
获取两次缓存运行记录后,对比以下指标:
指标检查要点
duration
若目标运行时长比基准慢10%以上需标记
status
若基准运行成功但目标运行失败需标记
cacheable_targets
注意可缓存目标数量是否变化
local_cache_target_hits
对比本地缓存命中数量
remote_cache_target_hits
对比远程缓存命中数量
is_ci
注意是否一个为CI环境运行,另一个为本地运行
计算缓存命中率:
  • 基准:
    (本地命中数 + 远程命中数) / 可缓存目标数 * 100
  • 目标:使用相同公式计算
  • 差值:
    目标命中率 - 基准命中率

Step 3: Analyze Cache Invalidation

步骤3:分析缓存失效原因

If cache hit rate dropped, the key question is: which target(s) caused the invalidation cascade?
Cache invalidation in
tuist cache
works the same way as in
tuist generate
:
  1. A "root cause" target has a direct change (source file modified, build setting changed, etc.)
  2. All targets that depend on the root cause target also get invalidated because their
    dependencies
    hash changes.
  3. This cascade can invalidate many targets from a single root change.
若缓存命中率下降,核心问题是:哪些目标导致了失效连锁反应?
tuist cache
中的缓存失效机制与
tuist generate
一致:
  1. “根本原因”目标发生直接变更(源文件修改、构建设置变更等)
  2. 所有依赖该根本原因目标的目标也会失效,因为它们的
    dependencies
    哈希值发生变化
  3. 单次根源变更可能引发大量目标失效的连锁反应

Identifying root cause targets

识别根本原因目标

Without the module cache target detail endpoint (available via MCP), use these heuristics:
  1. Check
    git diff
    between the base and head commits to see which files changed.
  2. Map changed files to their Tuist targets/modules.
  3. Targets with direct source changes are likely root causes.
  4. Targets that only changed due to dependency hash cascading are secondary invalidations.
在没有模块缓存目标详情端点(通过MCP提供)的情况下,可使用以下启发式方法:
  1. 检查基准与目标提交之间的
    git diff
    ,查看哪些文件发生了变更。
  2. 将变更文件映射到对应的Tuist目标/模块。
  3. 发生直接源文件变更的目标很可能是根本原因。
  4. 仅因依赖哈希值连锁变化而失效的目标属于次级失效。

Common root causes of cache invalidation

缓存失效的常见根本原因

CauseDescription
Source changesFiles in the target's source directory were modified
Resource changesAssets, XIBs, storyboards, or other resources changed
Build settingsTarget or project build settings were modified
Dependency changesAn external dependency version changed
Info.plist changesThe target's Info.plist was modified
Entitlements changesThe entitlements file was modified
Deployment targetThe minimum deployment target changed
HeadersPublic or project headers changed
Project settingsShared project-level settings changed
原因描述
源文件变更目标源目录下的文件被修改
资源变更资源文件、XIB、故事板或其他资源发生变更
构建设置变更目标或项目的构建设置被修改
依赖变更外部依赖版本发生变更
Info.plist变更目标的Info.plist文件被修改
权限文件变更权限文件(Entitlements)被修改
部署目标变更最低部署版本发生变更
头文件变更公共或项目头文件发生变更
项目设置变更共享的项目级设置发生变更

Step 4: Assess Impact

步骤4:评估影响

Categorize the cache invalidation:
  • Expected: Source files were intentionally changed, causing expected cache misses.
  • Unexpected: No source changes but cache was invalidated (build settings, Xcode version, etc.).
  • Cascade: A small change invalidated many downstream targets.
For
tuist cache
specifically, also consider:
  • Cache warming strategy: Was the cache run warming from scratch or incrementally?
  • The
    command_arguments
    field can reveal if different flags were used.
对缓存失效进行分类:
  • 预期内:源文件被有意修改,导致预期的缓存未命中。
  • 意外:无源代码变更但缓存失效(如构建设置、Xcode版本等因素)。
  • 连锁反应:微小变更导致大量下游目标失效。
针对
tuist cache
,还需考虑:
  • 缓存预热策略:缓存运行是从零开始预热还是增量预热?
  • command_arguments
    字段可揭示是否使用了不同的命令行参数。

Summary Format

总结格式

Produce a summary with:
  1. Overall verdict: Cache hit rate improved, regressed, or stable.
  2. Cache hit rate: Base rate vs head rate with delta.
  3. Duration: Absolute and percentage change.
  4. Root cause targets: Which targets had direct changes.
  5. Cascade impact: How many targets were invalidated due to dependency cascading.
  6. Recommendations: How to minimize cache invalidation.
Example:
Cache Run Comparison: base (run-123 on main) vs head (run-456 on feature-x)

Duration: 95.2s -> 142.8s (+50%) -- REGRESSION
Cache hit rate: 88% (44/50) -> 60% (30/50) (-28%) -- REGRESSION
Status: success -> success

Root cause: CoreModule had source changes (5 files modified).
This cascaded to 14 downstream targets that depend on CoreModule.

Cache invalidation breakdown:
- Direct changes: CoreModule (sources changed)
- Cascade: UIKit, Networking, Analytics, + 11 others (dependency hash changed)

Recommendations:
- Consider splitting CoreModule into smaller, more focused modules
- Use interface/implementation module pattern for frequently-changed modules
- Run `tuist cache` on the feature branch after rebasing to warm caches
生成总结需包含以下内容:
  1. 总体结论:缓存命中率提升、下降或保持稳定。
  2. 缓存命中率:基准命中率与目标命中率及差值。
  3. 运行时长:绝对时长和百分比变化。
  4. 根本原因目标:哪些目标发生了直接变更。
  5. 连锁影响:因依赖连锁反应导致多少目标失效。
  6. 建议:如何减少缓存失效的方法。
示例:
缓存运行对比:基准(main分支上的run-123) vs 目标(feature-x分支上的run-456)

运行时长:95.2s -> 142.8s(+50%)-- 性能下降
缓存命中率:88%(44/50)-> 60%(30/50)(-28%)-- 性能下降
状态:成功 -> 成功

根本原因:CoreModule发生源文件变更(5个文件被修改)。
该变更引发连锁反应,导致依赖CoreModule的14个下游目标失效。

缓存失效细分:
- 直接变更:CoreModule(源文件修改)
- 连锁反应:UIKit、Networking、Analytics,以及其他11个目标(依赖哈希值变更)

建议:
- 考虑将CoreModule拆分为更小、更聚焦的模块
- 对频繁变更的模块使用接口/实现模块模式
- 在特性分支变基后运行`tuist cache`以预热缓存

Done Checklist

完成检查清单

  • Resolved both base and head cache runs
  • Compared duration and cache hit rates
  • Identified root cause targets for cache invalidation
  • Analyzed cascade impact
  • Provided actionable recommendations for reducing cache misses
  • 已解析基准和目标缓存运行记录
  • 已对比运行时长和缓存命中率
  • 已识别缓存失效的根本原因目标
  • 已分析连锁影响
  • 已提供减少缓存未命中的可行建议