本期检索说明
先读取 content/collections/deep-radar 截至 2026-09-24 的全部原文链接,并按 URL、标题与补丁机制去重。最近 24 小时只有 2 项同时给出实测、源码级差异、原理解释与可迁移工程结论:一项来自 HotSpot C2 循环优化,一项来自 rustc Polonius/deferred liveness。Kotlin、Zig 与 Linux 的候选没有同时满足三项证据红线,因此不为领域配额凑数。
两项都仍在开放评审,结论必须带着边界读。C2 数据只测了 macOS AArch64 的生成代码尺寸,没有吞吐、编译时间或多架构结果;rustc 的两轮测量没有 primary instruction 改善,cycles 却出现两位数变化,作者也把它判断为噪声。后一项的价值不是“又一次加速”,而是公开展示如何用更可靠的指标否定一个看似合理的性能故事。
| 主题 | 原始发布日期 | 一手来源与交叉验证 | 截稿状态 | 推荐强度 |
|---|---|---|---|---|
| C2 消除 foreach 中重复的 induction-variable 检查 | 2026-09-24 23:20(中原标准时间) | OpenJDK PR #33058 / 完整 patch / macOS AArch64 代码尺寸 / C2 IdealLoop 实现 | 草稿 PR,尚未正式评审 | 推荐,重点看证明条件与代码尺寸边界 |
| rustc deferred liveness 清理的两轮 perf 反证 | 2026-09-24 22:21(中原标准时间) | rust-lang/rust PR #163266 / 完整 patch / 两轮 rustc-perf / 本地 Cachegrind 交叉检查 | 开放评审 | 推荐,重点看可靠指标与噪声处理 |
01 · JVM:把 ArrayList foreach 的两道边界检查移出主循环
原文与日期: Boris Ulasevich,2026-09-24 23:20(中原标准时间);OpenJDK PR #33058、完整源码 patch 与 C2 IdealLoop 源码。
为什么值得读: ArrayList 的增强 for 循环语义很普通,但经 ArrayList$Itr.next() 内联后包含 i >= size 与 i >= elementData.length 两道检查。两者都是 signed compare,既有 loop predication 不会提升它们;range-check elimination 只能通过 pre/main/post loop splitting 消除,结果是 foreach 比下标遍历生成更多代码。这个补丁的价值在于把“多了一个 Iterator”继续追到 C2 的比较类型、支配关系与循环分裂,而不是停在 Java 源码层。
核心技术结论: 补丁做两件事。第一,is_range_check_if() 在类型系统已证明 index 非负时接受 signed compare,让 i >= elementData.length 能被提升成 loop predicate。第二,新增 eliminate_redundant_iv_check():只有入口控制流证明首轮满足 init < limit(倒序循环则为 init > limit),并且循环体检查的 phi、limit 与主循环完全相同时,才把重复的 iv < limit / iv >= limit 折叠成常量。两道检查离开主循环后,不再需要为它们拆 pre/main/post loop。
// signed range check 只有在 index 类型下界非负时才接受
if (cmp->Opcode() == Op_Cmp(bt)) {
const TypeInteger* index = phase->_igvn.type(cmp->in(1))->isa_integer(bt);
if (index == nullptr || index->empty() || index->lo_as_long() < 0) {
return false;
}
}
// 循环体重复主循环条件时,替换为恒真/恒假
_igvn.replace_input_of(iff, 1, _igvn.intcon(always_taken ? 1 : 0));最有价值的实验、源码与 benchmark 细节: 在 release、macOS AArch64 上,仅统计 normal compilation 的 main code:LoopMaxUnroll=1 时 foreach 从 448 缩到 320 bytes,下降 28.57%;默认展开时从 512 缩到 432 bytes,下降 15.63%。indexed loop 分别保持 296 与 416 bytes 不变,说明改动瞄准 Iterator 内联后的冗余检查,没有把基线循环一起改写。PR 还给出更外层的对比:未限制展开时 foreach/indexed 为 792/672 bytes,限制展开时为 696/368 bytes,展示 loop splitting 与 unrolling 的叠加成本。
证据边界同样明确:这里只有代码尺寸,没有 ns/op、instruction count、i-cache miss、编译时间或 x86/RISC-V 结果;PR 仍是草稿且尚无正式 reviewer。工程复测应至少加入 JMH 吞吐、perf stat 的 instructions/branches/i-cache misses、C2 编译时间和多架构反汇编,并用含负初值、不同 stride、不可证明入口 guard 的负向用例确认新证明没有越界扩张。
适合的工程师背景: 熟悉 C2 IdealLoop、range-check elimination、loop predication,或正在排查“等价 Java 循环为何机器码体积差一倍”的 JVM 性能工程师。
预计阅读收益: 约 45–70 分钟;能掌握 signed range check 安全提升的证明条件、重复 IV check 的支配关系要求,以及用代码尺寸而非源码直觉定位循环膨胀的方法。
02 · Rust:两轮 deferred liveness 实验如何识别 perf 噪声
原文与日期: Rémy Rakic,2026-09-24 22:21(中原标准时间);rust-lang/rust PR #163266、完整源码 patch、第一轮 rustc-perf 与 移除可疑优化后的第二轮。
为什么值得读: 这项改动最初包含一个直觉上会变快的小优化:计算 Polonius 相关 deferred locals 时避免一次不必要分配,并清理 DenseLocationMap 的 Rc 持有关系。作者本地 Cachegrind 在 serde 热路径上看到小幅改善,但官方 perf 却报 secondary 指令回退、primary cycles 大幅改善。作者没有挑有利数字,而是删除唯一可能影响性能的 commit 再跑一次;第二轮仍出现相似的巨大 cycles 波动,从而把它识别为当日噪声。
核心技术结论: 当前 patch 主要把 LocalizedConstraintGraph 从持有 Rc<DenseLocationMap> 改为遍历时借用 &DenseLocationMap,并把 DeferredLocals 重命名为更准确的 DeferredRegionLiveness,减少所有权包装与中间访问器。真正可迁移的结论是:编译器改动若没有 primary instruction 信号,却只有 cycles 或 bootstrap 的大幅变化,不能据此声称优化;先做消融实验,再用 deterministic instruction count 与 Cachegrind 判断机制是否真实。
// 图结构不再拥有 Rc;调用者在遍历时传入共享借用
pub(super) fn new(
location_map: &DenseLocationMap,
outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
) -> Self { /* ... */ }
graph.traverse(body, borrow_set, location_map, &mut liveness_source, &mut visitor);最有价值的实验、源码与 benchmark 细节: 第一轮可靠指标 instruction count 没有 primary 变化;4 个 secondary 样本平均回退 0.3%(0.2%–0.4%)。Max RSS 有 1 个 secondary 回退 2.6%。但较不可靠的 cycles 却在 6 个 primary 样本上平均改善 10.3%(3.7%–16.6%),bootstrap 也只改善 0.36%。作者认为 html5ever 的约 17% cycles 改善不可信,并用本地 Cachegrind 复核。
删除唯一疑似优化 commit 后,第二轮依然没有 primary instruction 变化;secondary 同时出现 3 个平均回退 0.3% 与 4 个平均改善 0.8%。cycles 再次在 6 个 primary 样本上平均改善 10.3%(3.5%–16.6%),还夹着 1 个 secondary 回退 7.9%;bootstrap 反而回退 0.60%。几乎不变的补丁无法合理解释同幅度 cycles “改善”仍然存在,这就是消融实验揭露环境噪声的关键证据。
适合的工程师背景: 熟悉 rustc borrow checker/Polonius、MIR liveness、Cachegrind 或编译器性能基准,尤其适合需要判断 0.x% 指标是否可信的编译器与 CI 性能工程师。
预计阅读收益: 约 40–60 分钟;能学会按 instruction、cycles、RSS、bootstrap 的可靠性分层,并用删除优化 commit 的消融实验验证因果关系。
中国大陆 ToC 硬件价格观察
数据口径
窗口为 2026-08-26 至 2026-09-25,单位人民币,六类硬件固定同一 SKU。今天通过公开比价页的实时渲染结果复核到 CPU、GPU、主板、HDD、SSD 五类报价;DRAM 页面仍明确显示“暂无报价”,因此不新增点。重复价格作为真实采样保留,用来区分“已复核横盘”和“未取得数据”。SSD 只采用 2TB 规格全网比价栏,不采用跨容量聚合的“¥819 起”。
| 类别 | 9 月 25 日可复核价 | 30 日窗口内真实走势 | 建议 |
|---|---|---|---|
| CPU | Ryzen 7 9800X3D,京东 ¥2,619 | 9/3 ¥2,599 → 9/9 ¥2,449 → 9/23–24 ¥2,579 → 9/25 ¥2,619 | 观望或接近前低时入手;单日回升 1.55%,比窗口低点高 6.94% |
| GPU | MSI RTX 5070 VENTUS 3X 12G,亚马逊中国 ¥4,464.34 | 8/29–9/25 十一个真实点均为 ¥4,464.34 | 刚需可比价后入手;该渠道横盘,但与国内自营售后口径不可等同 |
| 主板 | ASUS TUF B850M-PLUS WIFI7,天猫 ¥1,299 | 8/31 ¥1,449 → 9/2–9/25 ¥1,299 | 刚需可入;较窗口首点低 10.35%,多次复核横盘 |
| DRAM | 暂无报价;最后可复核 9/9 ¥3,900 | 9/2 ¥3,900 → 9/5 ¥3,860 → 9/6–9/9 ¥3,900 | 观望;固定 SKU 缺价,不用其他容量、颗粒或时序替代 |
| HDD | IronWolf Pro 8TB ST8000NE001,i百联 ¥1,849 | 9/1–9/25 十个真实点均为 ¥1,849 | 容量刚需可买;先核对型号、五年保修与数据恢复服务 |
| SSD | ZHITAI Ti600 2TB,京东 ¥1,799 | 9/2 ¥1,919 → 9/23–25 ¥1,799 | 观望;可比价下降 6.25%,但样本仅四点且近期公开爆料高于比价栏 |
价格来源: 9800X3D、MSI RTX 5070 VENTUS 3X、ASUS TUF B850M-PLUS WIFI7、Kingston FURY DDR5-6000 32GB、IronWolf Pro 8TB、ZHITAI Ti600 2TB。
判断依据
CPU 今天从 ¥2,579 回升到 ¥2,619,仍处在 9 月中旬以来的震荡区间,尚无连续下跌证据。GPU、主板、HDD 与 SSD 都是实时复核后的横盘点;其中 GPU 是亚马逊中国渠道价,SSD 的同页近期爆料为 ¥1,889–1,919,均需要在下单前核对库存、发票和保修。DRAM 固定 SKU 仍无报价。由于五类中只有 CPU 发生单日变价,本期不把横盘外推为全市场趋势,也不依据少量样本预测继续下跌。
其它你可能关心的
- OpenJDK C2:修复 primitive unboxing 消除中的 dead-loop 自引用——IR 与崩溃栈说明充分,但属于正确性修复,没有性能实测。
- OpenJDK PPC64:压缩 oop 常量加载优化——源码改动明确,尚无公开代码尺寸或运行时 benchmark。
- Kotlin/Wasm:为 bridged lambda 补回 Kotlin 层 cast——有回归测试与 RCA,没有性能数据。
本期结论
C2 补丁展示了一个可迁移的优化套路:先用类型范围证明 signed index 非负,再用入口 guard 与相同 phi/limit 证明循环体检查重复,最终把 foreach 主代码缩小 15.6%–28.6%。rustc 案例则提醒,漂亮的 cycles 数字若没有 instruction count 和消融实验支持,可能只是噪声;删掉唯一疑似优化后,约 10.3% 的 cycles “改善”仍然存在,恰好推翻了性能归因。一个教你如何证明优化安全,另一个教你如何证明优化并不存在。