Search: #虚拟机优化

  1. 《对象、属性、Map,天哪!——动态语言的对象形状(Object Shapes)解析》

    《对象、属性、Map,天哪!——动态语言的对象形状(Object Shapes)解析》

    标签:
    #编程语言实现 #虚拟机优化
    #对象形状 #HiddenClass #内联缓存 #动态类型语言 #JIT编译优化 #内存布局

    总结:
    这篇博文讲解了动态类型语言(Python、Ruby、JavaScript 等)运行时如何用“对象形状”(maps / hidden classes)替代朴素的“哈希表存属性”模型。作者基于 CF Bolz-Tereick 的极简对象模型,用不足一页的 Python 代码完整实现了形状树、内联缓存(inline cache)的核心逻辑,并延伸到存储策略、类型冻结、类版本化等进阶优化,最后用 C++ 草绘了 V8、JSC、Skybison 等真实运行时的内存布局。

    文章要点:
    1. 朴素模型用哈希表存对象属性:虽然概念上是 O(1),但每次属性访问都要做字符串哈希、探测和一次额外的间接内存跳转,热路径上可能耗费成百上千条 CPU 指令。
    2. 形状(map/hidden class)同时解决三个问题:把字符串查找换成小整数偏移、让属性内联存储在对象内部消除间接跳转、作为不可变的稳定标识供快速比对——属性一旦变化就沿形状树换到新 map,旧 map 永不修改。
    3. 形状是持久化数据结构(树/字典树):所有空对象共享同一个空 map,按相同顺序加属性则共享同一形状;加属性顺序不同(如 a 后 b vs 反过来,或条件分支里赋值)会产生不同形状,这是实践中缓存命中率下降的常见原因。
    4. 内联缓存的工作方式:缓存“期望 map + 属性偏移”的组合,用指针相等(is)做极快校验,命中则直接按偏移加载;未命中走字符串慢路径并回填缓存——真机实现中快速路径内联、慢速路径外联,JIT 编译器还会进一步消除这层“解释态”。
    5. 形状与类是两个概念:不同类的对象可以有相同形状,这让内联缓存保持单态(monomorphic)、命中率更高;但也意味着形状不能作为类的代理(如 Ruby attr_reader 需要“类查方法 + 形状查偏移”两段式查找)。
    6. 进阶方向包括:给 map 附带类型信息(类型冻结,记录“该属性永远是 float”以减少守卫)、按存储策略单态化集合(空列表、小整数列表等专用布局)、类版本化,以及给真实运行时预留“溢出槽”处理对象估不准的大小。
    7. 实用启示:大多数对象字段很少(<20 个),Ruby 等运行时会在对象过大时退回哈希表模式;性能回归中缓存命中与未命中在热路径上可能有 2 倍以上的差距,Rails 等项目已有通过保持形状单态来优化 JIT 的实战 PR。

    URL:https://bernsteinbear.com/blog/object-shapes/

  2. 《在 GitHub Copilot 应用中流畅渲染超大 Pull Request》

    《在 GitHub Copilot 应用中流畅渲染超大 Pull Request》

    标签:
    #软件工程 #前端性能优化 #PullRequest #虚拟化渲染 #React #测量调度 #滚动锚定 #性能监控

    总结:
    文章介绍了 GitHub Copilot 应用如何重构 Pull Request 视图,使其能够流畅处理包含 2,200 个文件、超过 100 万行代码变更和 400 多条内联评论的超大型 PR。核心挑战在于评论高度的动态性——与代码行不同,评论高度取决于 Markdown 换行、可展开区块、回复框和图片加载等渲染时才能确定的因素。团队通过分离确定性与动态几何、实现智能测量调度器、采用滚动锚定技术,并建立自动化测量循环来解决这一问题,最终实现了百万行 diff 的流畅浏览体验。

    文章要点:

    1. 代码与评论的几何分离:代码行高度固定且可预先计算,而评论高度动态变化。团队将文档高度分为确定性代码高度(精确前缀和)和动态块高度(估算后测量),两者独立管理,避免评论调整时重建整个代码几何。

    2. 智能测量调度器:放弃每块一个 ResizeObserver 的方案(会触发反馈循环),改为单一的空闲和滚动门控测量通道。仅在视口附近约 2400px 范围内进行测量,屏幕上的块优先批量读取,离屏块最多做一次有限渲染,超过视口高度的块跳过测量。

    3. 滚动锚定技术:当测量高度与估算不符时,通过身份而非像素来校正——记录用户锚定的行或块,应用高度增量后,将同一锚点解析到新像素位置并滚动,确保用户视线不跳动。区分用户滚动与程序滚动,避免侧边栏切换等操作误触发保护机制。

    4. 数据管道优化:流式传输结构优先于内容,文件树和元数据在文档加载时即可渲染;语法高亮在主线程外运行,行先以纯文本显示;释放文档时保留最近几个 diff 的缓存,平衡内存与返回时的加载速度。

    5. 自动化测量循环:建立"变更→测量→改进"的无人值守循环,包括无头探针车道(声明式流程 + 生产环境插桩)和自动驾驶仪(驱动真实桌面应用),通过健康信号(如无未填充间隙、评论块非空)自动检测问题,实现机械式调试而非人工复现。

    URL:
    https://github.blog/engineering/user-experience/rendering-huge-pull-requests-in-the-github-copilot-app/ Rendering huge pull requests in the GitHub Copilot app

  3. 十亿行数据的虚拟滚动技术——HighTable 的五大实现方案

    十亿行数据的虚拟滚动技术——HighTable 的五大实现方案

    标签:#前端 #React #虚拟滚动 #性能优化 #大数据表格 #HighTable #DOM优化

    总结:本文介绍了 HighTable 组件实现十亿级数据表格渲染的五大核心技术:懒加载仅获取可视区域数据、表格切片只渲染可见行、无限像素技术通过缩放滚动条突破浏览器高度限制、双模式滚动实现全局跳转与本地精确定位、两步随机访问分离垂直与水平滚动逻辑。这些方案完全基于原生 HTML 与 CSS,无需 Canvas 或自定义滚动条即可在浏览器中流畅处理海量数据。

    文章要点:
    - 技术1:懒加载:仅加载可视区域单元格数据,通过 DataFrame 接口异步获取并缓存数据,将 1TB 数据缩减为仅需加载约 3KB 的可见区域
    - 技术2:表格切片:引入 Canvas 层作为定位参考,仅渲染可见行(约 30 行)而非全部十亿行,将 DOM 元素数量控制在恒定范围内
    - 技术3:无限像素:设置 Canvas 最大高度(800 万像素),超过阈值时通过 downscaleFactor 缩放滚动条分辨率,突破浏览器元素高度限制(Firefox 约 1700 万像素)
    - 技术4:像素级精确滚动:实现本地滚动(小幅度移动保持行连续性)与全局滚动(大幅度跳转)双模式,通过 globalAnchor 和 localOffset 状态管理,确保 2 万亿行内可达任意像素
    - 技术5:两步随机访问:解耦垂直与水平滚动逻辑,先计算目标位置并垂直滚动,渲染完成后再处理水平定位与焦点设置,支持键盘导航和程序化跳转至任意单元格

    链接:https://rednegra.net/blog/20260212-virtual-scroll/