<!-- title: 数据不是对象：一场得罪OOP的演讲 -->
<!-- domain: programming -->
<!-- video: https://www.youtube.com/watch?v=rX0ItVEVjHc -->

# 数据不是对象：一场得罪OOP的演讲

## 导语

2014年9月，首届 CppCon 大会在美国 Bellevue 举行。第一天主会场里，时任 Insomniac Games 工程总监的 Mike Acton 上台，用大约一个小时，把在座一半 C++ 程序员的舒适区拆了个遍：他质疑教条式面向对象、质疑“零开销抽象”的信仰、质疑大家引以为傲的类层次设计。这场演讲就是后来被反复引用的《Data-Oriented Design and C++》。

十二年过去，它在 CppCon 官方频道的播放量稳居历代演讲前列（百万量级，截至撰稿未做精确核实），每当性能话题冒出来，总有人把它翻出来重新吵一遍。它回答的问题今天依然扎心：为什么代码逻辑完全正确，跑起来却慢得离谱？为什么架构重构了三轮，CPU 时间一分没省？Acton 给出的答案是——大多数时候，问题不在代码写得好不好看，而在**数据怎么摆**。在 AI 推理吃满显存带宽的 2026 年回头看，这篇“老演讲”不但没过时，反而更锋利了。

## 视频背景卡片

| 项目 | 内容 |
|------|------|
| 视频标题 | Data-Oriented Design and C++ |
| 演讲者 | Mike Acton（时任 Insomniac Games 工程总监） |
| 频道 | CppCon 官方频道 |
| 发布时间 | 2014年9月（首届 CppCon） |
| 时长 | 约60分钟 |
| 播放量 | 百万量级（截至2026年9月，未精确核实） |
| 核心主题 | 数据导向设计（Data-Oriented Design, DOD） |

## 核心内容拆解

### 1. 世界观纠偏：程序的本质是变换数据

Acton 全场第一记重锤（视频原话，大意）：**所有程序、以及程序的每一个部分，其目的都是变换数据**。不是“表达思想”，不是“给现实建模”，就是变换数据。软件的上游是数据的来源——传感器、文件、网络包、玩家输入；下游是数据的去向——屏幕、存档、网络。程序员写的一切代码，本质上都是夹在中间的变换器。一旦把“设计优雅的类层次”当成目的本身，就把手段当成了目的。

**【延伸分析】** 这个观点放到今天更狠：大模型推理本质上就是一批张量进来、一批概率分布出去，推理框架的全部优化功夫几乎都在数据搬运效率上。Acton 十二年前说的“变换机器”，就是今天 GPU 集群的日常——你要是去看 vLLM 或者 TensorRT 的优化文档，会发现满篇都是他的影子：批处理、内存布局、带宽利用率。

### 2. 三个问题，比设计模式值钱

Acton 介绍了他在 Insomniac 团队里的审码习惯：拿到任何模块，先问三个问题（大意）——**数据在哪？数据从哪来？数据要到哪去？** 听起来朴素得像废话，实际上它把技术讨论从“这个类该怎么设计”拉回到“数据的存取路径怎么走”。很多团队评审代码时争命名、争分层、争设计模式，唯独不问数据流，最后性能问题全都出在没人看的地方。

**【延伸分析】** 这其实是数据库工程师的本能动作：查询计划、索引设计、I/O 路径，核心全是“数据从哪来、到哪去”。对你我的日常意义在于——review 代码时先画数据的生命周期，再谈架构是否优雅，顺序不能反。

### 3. 成本模型：抽象不是免费的

C++ 社区爱讲“零开销抽象”，Acton 不买账。他的主张是：**每个操作都有成本**，工程师的任务不是假装成本不存在，而是心里有一张成本表，知道自己在为什么付钱（视频原话，大意）。

**【背景补充】** 这里借用业界流传已久的 latency numbers（出自 Jeff Dean 等人的经典分享，非视频精确原话）：从 L1 缓存取一次数据约 0.5 纳秒，跨到主内存约 100 纳秒，差了两个数量级；一次缓存未命中（cache miss）足以让 CPU 空转上百个周期。你以为的“访问一个对象字段”，物理上可能是一次横跨数百周期的内存往返。抽象什么时候免费、什么时候不免费，靠的是成本模型，不是信仰。这也是 Acton 全场反复敲的黑板：写代码之前，先想清楚目标成本是多少。

### 4. 布局即性能：AOS 输给 SOA 的那一战

这是全场最硬核的演示环节。同一批数据，用 AOS（Array of Structures，数组套结构体）和 SOA（Structure of Arrays，结构体套数组）两种摆法，性能能差出几倍甚至几十倍。原因很物理：CPU 从内存拿数据是按缓存行（通常 64 字节）整块搬运的。密集数组加顺序扫描，每一趟缓存行都满载利用；而对象指针满天飞的写法，每次解引用都可能是一次 cache miss，术语叫 pointer chasing——CPU 大部分时间在等内存，而不是在算。

他还把数据库领域的“规范化”概念搬进了游戏数据设计：数据里别放冗余，能算出来的东西别存两份。**【延伸分析】** 今天游戏圈的 ECS 架构——Unity 的 DOTS、Rust 生态的 Bevy——正是这一页幻灯片的产品化：把“数据怎么在内存里排”当成架构的第一性问题。

### 5. 分支和虚函数的隐性账单

现代 CPU 靠流水线和分支预测喂饱自己，一旦猜错分支，流水线就要清空重来，代价从十几个到上百个周期不等；虚函数调用则可能让编译器放弃内联优化，还可能带来间接跳转的额外开销。Acton 现场演示了 Insomniac 引擎里的真实优化手法：把数据排序让分支变得可预测、在热点循环里用无分支写法（branchless）替代条件跳转，吞吐量立刻上去。

要说清楚的是，他不是让你把全部代码写成汇编风格，而是**值得只留给热点路径**：全程序 90% 的时间花在 1% 的代码里，那 1% 才配得上这种待遇。**【延伸分析】** 这套思路后来被更多语言圈消化：Rust 把内存布局和所有权写进了语言设计本身，数据库内核圈全面转向列式存储，本质都是“先按硬件的脾气摆数据”。

### 6. 别为不存在的未来写代码

全场最“得罪人”的部分，是对教条式 OOP 的清算（大意）：封装被滥用了，类层次越长越没人敢动；所谓“通用框架”写了一年，业务问题还没解决。他的主张激进而简单：**先解决手头这个具体问题**，等模式真的重复出现了再抽象。他还点了一句很多工程师不爱听的话——如果你写代码是为了应对假想中的未来需求，那你大概率在浪费公司的钱。

**【延伸分析】** 我的看法是：这不是反 OOP，是反未经核算的信仰。封装本身没错，错的是把“万物皆对象”当成不需要论证的公理。有意思的是，这十二年各语言生态基本都在朝他指的方向走——说明当年台上台下那场不愉快，时间站在了 Acton 这边。

### 7. 一切以实测为准

贯穿全场的最后一根线：别猜，测。Acton 反复强调，优化决策必须来自分析器（profiler）的数据，而不是工程师的直觉。Insomniac 的引擎团队是按“每帧预算”干活的——60 帧意味着一帧只有约 16.7 毫秒，每个子系统分到多少微秒，超了就砍功能或换算法。**【延伸分析】** 普通业务开发完全可以borrow这套纪律：给关键接口定 P99 预算，在 CI 里挂性能回归测试，让“变慢了”变成流水线上可见的红灯，而不是用户投诉后才知道的事故。

## 知识结构图

```mermaid
flowchart TD
    A["软件的目的：变换数据"] --> B["先问数据在哪、从哪来、到哪去"]
    A --> C["认清硬件的真实成本"]
    A --> D["数据布局先于代码结构"]
    C --> C1["缓存未命中是头号瓶颈"]
    C --> C2["分支预测会失败"]
    C --> C3["抽象并非免费"]
    D --> D1["密集数组优于指针散布"]
    D --> D2["数据规范化去冗余"]
    D --> D3["SOA替换AOS"]
    C1 --> E["热路径按流水线大块变换"]
    D1 --> E
    D2 --> E
    E --> F["一切以分析器实测为准"]
```

## 实战启示

看完这场演讲，你能直接带走的东西，我按投入产出比排个序：

**第一，把“数据三问”写进 code review 清单。** 每次评审先问：这份数据在哪、从哪来、到哪去、被读写几次。很多性能问题在这一步就能暴露，根本轮不到 profiling。

**第二，先测量，再动手。** 装个 perf 或生成 flamegraph，找到真正的热点再优化。凭感觉优化是这门手艺里最昂贵的自嗨——Acton 整场演讲就是一部“反直觉优化”纪录片。

**第三，给热点路径上三板斧：** 数组化、去掉指针追逐、消灭热循环里的不可预测分支。具体来说，把嵌套指针结构摊平成连续数组；频繁一起访问的字段放一起（利用 64 字节缓存行）；能排序先排序，让分支变成规律模式。注意，只做热点，别全库推翻——那是另一场灾难。

**第四，跟自己签一份“性能预算”。** 关键接口写清楚 P99 上限，CI 里跑基准测试，劣化超过阈值就报警。游戏行业用“每帧 16.7 毫秒”管了二十年，这套纪律在任何延迟敏感的系统里都成立。

**第五，AI 时代的新读法。** 就算你天天写的是 prompt 和 agent 编排，也一样在“变换数据”：批量处理胜过逐条循环、上下文按访问模式组织、缓存命中率决定成本——把这四个词记住，你已经比多数调 API 的人更懂推理成本了。

## 延伸学习路径

1. **《Data-Oriented Design》（Richard Fabian）** — DOD 体系最系统的成书，作者在官网提供免费在线全文，适合当作本演讲的“课后教材”。
2. **Unity DOTS 官方资料** — 看 ECS 和 Job System 如何把“数据布局优先”产品化，文档里大量设计动机与 Acton 的论点一一对应。
3. **Latency Numbers Every Programmer Should Know** — 一页纸的延迟量级速查表，背下来，成本模型就有了地基。
4. **CppCon 官方频道历年演讲** — 同类主题推荐 Chandler Carruth 关于“零开销抽象”反思的演讲，可以看作对 Acton 的隔空回应。

## 一句话总结

**性能的胜负手在数据的摆法，不在代码的修辞——先问数据在哪，再谈对象怎么设计。**

## 参考来源

1. [Data-Oriented Design and C++ — Mike Acton, CppCon 2014](https://www.youtube.com/watch?v=rX0ItVEVjHc) — 本文解读的核心视频
2. [Data-Oriented Design（Richard Fabian，官网免费在线版）](https://www.dataorienteddesign.com/dodbook/) — DOD 思想最系统的成书
3. [Unity DOTS](https://unity.com/dots) — 数据导向设计在商业引擎中的产品化
4. [Latency Numbers Every Programmer Should Know](https://gist.github.com/jboner/2841832) — 程序员必背延迟量级速查表
5. [CppCon 官方频道](https://www.youtube.com/@CppCon) — 历年演讲原始出处

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
