过去一年,开发者社区里流传着一个听上去很合理的判断:让大模型写代码时,动态类型语言比静态类型语言更划算,因为省掉了类型声明,代码更紧凑,消耗的 token 更少。这个说法被反复引用,甚至连搜索引擎的 AI 摘要都照单全收——搜索「动态与静态语言的 token 成本」,Google 的 AI 概览开头就是「动态类型语言的 token 成本通常低于传统静态类型语言,因为省略显式类型声明让代码更紧凑」,并引用了同一篇文章作为依据。

技术博主 Dan Luu 决定动手验证。他跑了两轮真实规模的评测,结论是:这个被广泛传播的判断,基本站不住脚。
被引用最多的那份数据,题目太简单了
流行说法的源头是一份对比实验,作者从 Rosetta Code 上取题,测量不同语言解同一道题需要多少 token。结果显示,最费 token 的 C 语言与最省的 Clojure 之间存在 2.6 倍的差距;后来又补测了数组语言 J,平均只需 70 个 token,几乎是 Clojure(109 个)的一半。作者由此推断,如果 token 效率真的成为关键驱动力,这可能会成为编程语言演化的一个有趣方向。
问题恰恰藏在这组数字里。Dan Luu 指出,一道能用 70 个 token 解决的题目,根本算不上题目。这类琐碎任务里,大部分工作只是把答案打印出来,性能表现无法推广到需要真正干活的场景。他此前在评测「穴居人模式」提示词时就见过同样的现象:在极简任务上宣称的巨大收益,一旦换成稍微需要动脑的问题就消失了。
另一份支持相同结论的对比实验,毛病更隐蔽。其中一项测试执行了一条并不存在的路径,导致失败;后面某个智能体把这条不存在的路径符号链接到了自己的可执行文件,测试通过了,但代价是此后所有测试都在跑那一个智能体的可执行文件。原作者据此分析 Rust 为何出现失败,实际上只是因为 Rust 的评分环节跑在 Go 智能体做符号链接之前。
两个真实项目:zstd 解码器与 Pandoc
Dan Luu 的做法是自己造评测,并且在看结果之前先公开写下预测。他给出的三条预注册判断是:95% 的把握认为动态与静态语言的整体差异说法不成立;60% 的较低把握认为在超高算力档位下静态语言会稍占上风;98% 的把握认为 J 这类「怪语言」的优势不会成立。
第一轮评测的任务是实现一个完整的 zstd 解码器。智能体拿到 zstd 的 RFC 文档和勘误,被关在没有网络的容器里,不提供测试用例。模型统一用 GPT-5.6 Sol,分 medium 与 ultra 两档算力投入。之所以不给测试,是因为像 zstd 这种覆盖面的项目,测试不可能穷尽所有分支——Dan Luu 本人就曾在这个久经考验的软件里找到过数据损坏的缺陷。
结果分成两层:只看 medium 档,动态语言的确聚集在成本更低、正确率更高的那一侧,看上去支持流行结论;但换到 ultra 档,格局就乱了,排在前列的反而以静态语言居多。真正稳定的规律不在动静态之分上,而在两个别的维度——汇编这类对人类也极其费劲的语言表现明显更差;冷门语言同样吃亏,合理的解释是各家 AI 实验室在小众语言上投入的合成训练数据极少甚至为零。把语言流行度和评测表现放在一起看,能观察到一个弱到中等的正相关:越主流的语言,写出来的代码往往既更正确又更便宜。这与第一份实验推崇 J 这类高密度语言的方向正好相反。
第二轮换了完全不同的任务与呈现方式。Dan Luu 把 ProgramBench 的 Pandoc 评测改造了一下:不做原本的逆向工程题,而是把 ProgramBench 的材料连同测试一并交给智能体,再用一组留出测试来打分,更接近测试驱动开发的节奏。结论依旧:成本与得分和语言的动静态属性没有明显关系,冷门语言仍然吃亏,汇编依旧垫底,而 Clojure 在这一轮比在 zstd 那轮好得多。
Clojure 在第一轮翻车有具体原因:40 次 medium 运行里有 36 次、40 次 ultra 运行里有 5 次出现测试失败,症结是字节转换在 128 到 255 区间抛出异常,或许应该改用 unchecked-byte。这也是一个真实存在的成本——如果没有测试兜住,这类错误会一路带到线上;即便有测试,修它同样要烧掉时间和 token。
哪些流行判断被证伪了
对照两轮数据,几条在社区里流传甚广的说法可以做初步清算:
- 「代码质量参差的语言(比如 PHP)在大模型手里表现更差」——在这两项任务上不成立
- 「既然重写成本变低了,就该用表达力强的语言(比如 Haskell)」——同样不成立
- 「应该选流行语言」——有弱支持
- 「动态语言在小项目上占优,项目变大后被静态语言反超」——这两项任务不支持这一判断,不过两个任务的形态和呈现方式差异太大,无法确定究竟是规模因素还是别的变量在起作用
回看他自己的三条预注册判断,第一条和第三条被证实,第二条(ultra 档静态语言稍好)信息不足,若必须二选一,他倾向于判定为错误。
值得留意的是这套方法本身的意义。Dan Luu 提到,2014 年他梳理过静态与动态类型的学术文献,除少数案例研究外收获寥寥。以一篇典型论文《静态类型系统能改善软件系统的可维护性吗?一项实证研究》为例:33 名受试者被分配修复既有代码中的错误或补全存根方法,静态组用 Java,动态组用 Groovy,采用被试内设计并随机化任务顺序。结论是类型错误场景下 Java 组更快,语义错误场景下没有差异。但该研究刻意回避了循环、递归等复杂控制结构以降低耗时方差,导致所有缺陷都是琐碎缺陷,中位解题时间只有几百秒——这恰恰是最不耗费职业程序员时间的那类问题。
大模型改变了这件事的可行性。让智能体实现一个 zstd 解码器大约花费 20 美元,乘上语言数量和每种条件下的重复次数确实不便宜,但相比雇一位能读懂 zstd 规范并动手实现的职业程序员,这个数量级的研究此前根本不可能做,Pandoc 那一轮更是如此。许多原本无从回答的问题——什么测试手法有效、什么软件架构适合、修缺陷的成本是否因语言而异——如今至少有了动手一试的可能。
至于最终答案,Dan Luu 的态度相当克制:绝大多数关于「某语言特别适合大模型」的流行断言看起来都是错的,但什么才是对的,目前还不清楚。
来源:danluu.com(Dan Luu)







