1. 先把话说清楚:代码生成优化到底在优化什么
这两年只要聊到写代码,基本绕不开“代码生成”四个字。不管是用大模型辅助写业务逻辑、自动补全接口调用,还是拿 Simulink 这类建模工具直接生成嵌入式 C 代码,“生成”本身已经不是稀罕事。真正拉开差距的,是生成之后那一步——优化。我见过太多人拿到生成代码直接一把梭,跑通了就算完事,结果要么冗余函数堆成山,要么内存申请释放乱七八糟,要么算法逻辑在边界条件下出错。说到底,代码生成优化不是“改改变量名、缩缩行”这种表面功夫,而是从正确性、性能、可读性、可维护性四个维度重新审视生成结果,把它从“能跑”打磨成“好用”。
先给读者一个共识:代码生成优化适合谁?如果你在用大模型辅助写业务代码,想减少返工;如果你在做嵌入式开发,模型生成的 C 代码需要过静态检查和代码评审;如果你是技术负责人,关心生成代码能不能进生产环境——这篇文章就是写给你看的。我在这块踩过的坑不少,早期吃过“生成一时爽,集成火葬场”的亏,后来慢慢总结出一套可以复用的优化套路,先把框架梳理清楚,再逐层拆解。
以我的经验,代码生成优化本质上是三层工作:第一层是语义对齐,确保生成的代码和需求描述真正一致,不能只是“看起来像”;第二层是资源效率,去掉无意义的计算、存储、调用开销;第三层是形态塑造,让代码符合团队的编码规范、架构约束和可测试性要求。这三层没有严格的先后顺序,但在实操中我习惯先保证语义正确,再谈性能,最后调结构。为什么是这个顺序?因为一个语义都错的代码块,性能再漂亮也是空中楼阁;而结构问题通常不影响功能,却会影响后续所有人的维护成本,所以放在最后但绝不能不重视。
这里还想强调一个很多人忽略的点:代码生成优化不是一个一次性动作,而是一个伴随代码生命周期的持续过程。需求变了、运行环境变了、数据规模变了,原来“优化好”的代码可能再次变成瓶颈。所以我后面分享的方法里,会特别注重“可复验”和“可回归”,让优化动作本身也变成一种可持续的工程能力,而不是一锤子买卖。
2. 代码生成为什么需要优化:先搞懂生成器的“脾气”
2.1 两种主流路径的先天差异
要理解优化,先得理解生成器的行为模式。现在市面上主流代码生成路径无非两种:一种是基于大模型的自然语言到代码生成,另一种是基于领域模型(如 Simulink、状态机工具)的代码自动生成。这两条路径的“脾气”完全不同,优化侧重点也完全不同。
大模型生成的代码,特点是自由度高、风格接近人类但不稳定。同一个需求,换一种 prompt 措辞,可能生成完全不同的实现方案;换一个模型版本,可能从递归改成迭代;温度参数调高一点,甚至出现函数名都拼错的情况。这种不确定性决定了优化重点在“约束”和“验证”——你得用评审规则、静态检查、测试用例去收拢它的自由度,把生成结果拉回团队规范内。
而 Simulink 这类模型生成工具,恰恰相反:它确定性极强,同样的模型和配置生成结果基本一致,风格统一到像印刷体。但它的顽疾也很典型:过度工程化。为了保持模型和代码的映射关系,生成的 C 代码往往包含大量中间变量、多层级函数调用、甚至几十行只有注释价值的宏定义。我在实际项目里见过一个加法模块生成的代码,函数嵌套深度超过五层,实际干活的就一句话。这种代码优化重点就变成了“消冗”和“等价变换”——保证行为不变的前提下,压缩体积、减少调用开销、合并冗余路径。
所以说,代码生成优化不是一套方法走天下。你得先识别自己面对的是哪种生成器、哪种特性在拖后腿,再选择对应的优化策略。
2.2 审题不清是最大的浪费源
代码生成优化有一个经常被忽略的前提:你得先确认需求本身是对的。我见过不少新手,拿到一个需求描述就开始调 prompt 或者拖模型,生成出来一版代码就开始优化性能。结果优化到一半发现,产品经理要的是计算日均值,模型生成的是累加和——方向错了,后面全白做。
这里我建议的实操方法是:在进入优化环节之前,强制自己做一次“需求回读”。把原始需求拆成原子条件,列出输入输出、边界行为、异常处理三个清单,拿着清单去比对生成代码。尤其是边界条件,比如空集合、重复元素、极值输入、并发冲突,这些是生成代码最容易“装糊涂”的地方。宁可多花半小时做核对,也不要省掉这步直接上优化工具,否则你很可能在为一个错误实现做加速。
另外提一个和大模型协作时的技巧:生成代码之前,在 prompt 里明确写出“请先列出需求假设,再生成代码”,这能很大程度减少自说自话式的实现偏离。算是 prompt 层面的一种“前置优化”,也算是代码生成优化链条的第一环。我自己用了很长一段时间,稳定有效。
2.3 运行环境约束下的二次适配
生成代码的优化还必须考虑运行环境。同一段生成的代码,跑在 x86 服务器上和跑在 ARM Cortex-M 微控制器上,优化策略完全不同。服务器上你可能在乎吞吐量和内存占用,边缘设备上你得抠每条指令周期和栈空间。我遇到过代码生成工具生成了一份全功能模块代码,直接编译进嵌入式工程,Flash 直接超了 30%,后来不得不做功能裁剪和存储优化才压下来。
所以在做代码生成优化时,脑子里要时刻挂着“部署目标”这个约束。如果是通用场景,优化重心放在算法复杂度和可扩展性;如果是资源受限场景,优化重心要前移到“这个功能是不是非做不可”“缓存放这里合不合适”“这个模块能不能合并到上一个”。环境决定了优化的上界,也定义了优化的边界条件。脱离环境谈优化,等于不看地图聊导航。
3. 代码生成优化的四个核心维度
3.1 正确性:优化第一步不是跑得快,而是不跑错
代码生成优化的第一维永远是正确性。这里说的正确性不光是单元测试全绿,还包括边界语义、错误处理、可重入性、时钟时序这类高级语义。我遇到过最典型的例子:用大模型生成一个处理 CSV 文件的代码,功能写完了,日常数据测试也过了,但文件末尾多一个换行符时直接解析出错。问题就出在边界状态没有覆盖。这种 bug 在生成代码里极其隐蔽,因为它不是逻辑大错,而是少了一个状态判断。
针对正确性维度,我的优化套路是三步走。第一步,给生成代码补一个“防御性外壳”:对入参做合法性判断、对返回值做异常兜底、对资源申请做失败分支。很多生成代码默认数据永远合法,这在真实环境里根本站不住脚。第二步,建立边界测试矩阵:空值、极值、非法值、重复值、并发调用,每个维度都要有用例。第三步,跑一轮“负反馈测试”,主动制造异常环境,比如磁盘写满、内存分配失败、超时,看生成代码是否会优雅失败还是直接崩掉。这三步走完,正确性基本有了底,后续优化才有意义。
3.2 性能:从算法复杂度到常数级抠门
性能优化是大家最容易关注到的维度,但也是最容易做偏的。代码生成场景下,我观察到两种极端:一种是不管三七二十一,所有代码硬套“最优算法”;另一种是连冒泡都没优化就直接上。
先说算法层面:如果生成代码里出现了明显的次优算法——比如应该用哈希表的地方用了全表遍历、应该用二分查找的地方用了线性查找、应该用动态规划的地方用了暴力递归——那第一步肯定是换算法。这块大模型经常出问题,特别是对数据规模不敏感时,它可能默认给你一个最简单但复杂度高的实现。我在优化时通常会先问一句:这个函数会不会成为热点?数据规模可能到多大?未来会不会增长?如果答案都是“会”,那直接重写,不犹豫。
但算法优化不是全部。生成代码的性能问题,更多时候出在常数级开销上:频繁的容器拷贝、无意义的类型转换、重复计算不缓存、循环里面调昂贵操作。这些虽小,堆起来很可观。我做过一个实际项目,生成的报告模块初始化时要拼一个冗长的字符串,生成器给每个拼接操作都新建了一个临时字符串对象,数据量一上去,接口延迟直接翻倍。优化方式很简单:改成一次性缓冲写入,性能立刻恢复。所以说,性能优化要算法和常数两手抓,大结构省时间,小细节省机器。
3.3 可读性:给三个星期后的自己留条活路
代码生成优化里最容易轻视的是可读性。为什么?因为生成代码“当时看起来”总是整洁的,而且很多人天然觉得“机器写的代码应该也是规范的”。但现实是,生成器生成的函数名经常含义模糊,命名风格跟团队不一致,关键步骤缺少注释,控制流复杂到让人怀疑人生。等你三周后再回来看这段代码,得跟解谜一样才能弄懂它在干什么。
提升可读性的优化动作包括:重命名变量和函数,让名字说人话;拆分超长函数,按单一职责拆成小函数;补充模块级注释,说清楚“这段代码为什么存在”“和模型哪个模块对应”“边界条件是什么”。特别是 Simulink 生成的代码,变量命名经常带生成器后缀,比如tmp_xyz_0之类,如果直接进版本库,后期排查问题会非常痛苦。我会在生成后加一个“命名清洗”步骤,把信号名、状态名映射成业务语义明确的标识符,虽然不改变逻辑,但维护效率能提升好几个档次。
还有一个容易被忽略的可读性细节:生成代码的版本留痕。每次优化改动前,先把生成器版本、配置参数、模型版本记下来。否则三个月后你发现生成代码和当前模型对不上,想找差异都无从下手。这一点在嵌入式团队里尤其重要,强烈建议养成习惯。
3.4 可维护性:让优化动作可复现可回归
第四维是可维护性。这层优化很多人意识不到,因为它不直接在代码里体现,而是体现在你的优化流程里。一句话:你的优化动作本身,得是能重复执行的脚本,而不是纯手工一次又一次地改。
举个例子:你手工优化了一版生成代码,修复了三个性能热点。但接下来如果模型更新,重新生成代码,你的优化就全丢了。所以我会把优化动作尽量“外置成工具链”:性能热点用脚本自动检测,命名清洗用映射表自动替换,防御性外壳用模板自动包裹。这样每次重新生成代码后,优化脚本可以快速重放,保证手工价值不流失。
这套可维护性思路往大了说,就是建立一套“代码生成+自动优化+回归验证”的流水线。生成代码提交之前,自动跑一遍静态检查、复杂度分析、单元测试,不合格的自动打回。我负责的团队从人工评审转型到这套半自动流程之后,代码评审工作量至少降了 40%,而且漏网的问题明显减少。优化从“一次性手艺活”变成“可复现的工程能力”,这才是代码生成优化真正值钱的地方。
4. 实操:一套可直接复用的代码生成优化流程
4.1 准备阶段:先给生成代码建基线档案
正式开始优化之前,先把“优化前长什么样”记录下来。我会做三件事。第一件事:记录生成环境,包括生成工具或模型版本、关键参数、输入模型或 prompt 原始版本,这一步能保证优化过程可回溯。第二件事:跑一遍完整的基线测试,包括功能测试、性能基准、内存画像,把被测数据记录下来。第三件事:跑一次静态分析,记录圈复杂度、重复率、关键路径耗时,这些数值后续可以作为优化成效的对比基准。
别小看这个准备阶段。我现实中遇到不少同事,优化前不做基线,改完代码后只说“感觉快了”,问他快了多少,没有数据支撑。后来我把基线记录当成强制步骤之后,所有人汇报优化成果都开始说“平均延迟从 120ms 降到 48ms,吞吐从每秒 300 涨到 610”。老板看着也直观,同事也认可,这工作才有说服力。
另外提醒一点:基线的数据要尽量贴近真实生产环境。如果生产环境是低配机器,就别拿开发机的高配数据当基准。我之前做过一个项目,开发机上性能测试全绿,到了产线低配机直接超时,后来才意识到基准环境的差异才是元凶。这个坑希望你别踩第二遍。
4.2 执行阶段:从大结构到小细节逐步下刀
我习惯把优化执行分成三个层次,确保不漏项、不返工。
第一层:结构与算法层。先把生成代码的整体结构捋一遍,识别有没有多余的抽象、冗余的中间层、可合并的模块。对热点函数做算法评估,该换数据结构的换数据结构,该降低复杂度的降低复杂度。这一层解决的是“根本性”的性能问题,通常能带来量级上的提升。
第二层:资源与开销层。逐行审视关键路径上的代码,找常数级浪费:重复计算、临时对象、无意义的日志打印、循环体内的开销操作。这一层更琐碎,需要有点耐心,但收益是实打实的,适合用性能剖析工具辅助定位。
第三层:代码形态层。做命名清洗、加注释、拆长函数、对齐团队规范。这一层不影响功能,但决定代码能不能通过评审、能不能被团队愉快地维护。三个层次做完之后,再整体跑一遍测试和静态检查,确保优化没有引入新问题。
整个执行过程我强烈建议用“小步快跑”的节奏:每完成一个层次的优化,就保存一次版本,跑一轮回归测试。不要想着三个层次一口气改完再验证,那样出了问题很难定位是哪一步引起的。我用这套节奏踩坑的次数明显下降。
4.3 验证阶段:不止看功能,还要看画像和回归
优化做完之后,验证环节不能省。验证分三块:功能验证、性能验证、兼容性验证。
功能验证最简单也最基础:跑一遍完整测试套件,边界用例、异常用例都过一遍。这部分如果之前建立了好的测试矩阵,现在就能发挥价值。性能验证则需要拿基线数据做对比,关注的不只是“快了没有”,而是“哪个指标快了多少”“有没有指标反而变差了”。有时候优化会牺牲内存换速度,这时候要把 trade-off 明确标记出来。兼容性验证则要确认优化后的代码在不同编译环境、不同依赖版本下都能正常构建和运行。生成代码经常踩的一个坑是用了某版本编译器特有的语法或库函数,换环境就编译失败,这部分在验证阶段提前发现,能省下后面很长一段 debug 时间。
验证通过之后,把这些结果连同基线档案一起提交到文档或 commit message 里。你会发现,这套“留痕”习惯,在代码评审和技术复盘时特别有用,也是老手和新手之间一个很直观的差别。
5. 典型场景实战:不同路径下的优化侧重
5.1 Simulink 模型生成 C 代码的优化要点
Simulink 模型生成 C 代码是很典型的高确定性生成路径,优化侧重点非常清晰:保持模型与代码的可追溯性基础上,做存储和执行效率的收敛。
我实际优化过一个车辆控制模块生成代码,问题集中体现在三个方面:一是生成的中间变量过多。模型里一个小信号线,生成的代码可能对应一个全局变量或一个大结构体成员,密密麻麻看得人头疼。优化方式是设置代码生成选项里的“信号存储复用”或“局部变量优化”,让中间量变成函数内临时变量,既省内存又提高可读性。二是函数层级过深。模型里模块嵌套多了,生成代码的函数调用链很长,嵌入式环境下调用开销和栈压力都会增加。优化方式是配置“函数打包”选项,把若干个叶子模块打包成一个函数,减少调用层级。三是不必要的全局数据。模型里有些常量和只读参数被声明成全局变量,优化思路是把它们改成#define宏或者const局部常量,减少数据段占用。
还有一个自动化的小技巧:对生成代码做一次基于差分的目标代码对比。把优化后的代码和优化前代码编译后的二进制反汇编进行比对,确认功能逻辑完全等价。看起来有点繁琐,但遇到那种“性能优化但行为在极端情况出现偏差”的诡异 bug 时,这个手段能快速帮你圈定差异范围。
另外,Simulink 生成的码还有一个很常见的问题,就是代码里塞了大量用于可视化和 debug 的辅助宏。发布版本里这些都不应该存在。优化时可以统一加-D编译宏把它们关掉,或者通过配置关闭调试信息生成。很多团队忘记这一步,导致发布固件体积虚胖、运行时不明显但确实存在的性能拖累。
5.2 大模型辅助代码生成的优化实战
大模型辅助生成代码的优化,场景更多变,因为代码质量高度依赖 prompt 和模型能力。这里我分享一下自己压箱底的“优化三步法”。
第一步是“语义稳固”。拿到生成代码后,先不看代码本身质量,只看它是否完整实现了需求。这步用前面说的需求回读法,列出原子条件逐条核对,发现问题立刻让模型重新生成,不要手动修。因为在生成阶段纠偏,代价远低于后续手工改。第二步是“结构收敛”。当生成代码通过了语义核对,再审视代码的组织形态:函数拆得是否合理、依赖是否清晰、有没有不必要的单例或全局状态、接口设计是否方便测试。这个阶段发现的问题,优先改 prompt 的约束条件来解决,比如“请用纯函数风格”“请保持模块无状态”“请用明确的数据传递而不是共享全局变量”,让下一次生成更接近标准形态。第三步是“最终润色”。当结构和语义都没问题后,最后再补充防御性代码、注释和边界处理。这一部分如果每次都要手工加,我会把常用的防御模板放进自己的代码片段库,生成后快速补齐。
我在和 DeepSeek 生成论文相关代码时也用到过类似思路。先把目标拆成一小段一小段需求,每段生成后再拼装,比一次性生成超大段代码再优化要稳定得多。人有专注带宽上限,模型也一样,生成范围控制得越小,质量控制越容易。
5.3 优化手法要区分“一次性”和“可持续”
最后想特别提一个容易被忽略的视角:优化动作本身也是分类型的。有些优化是“一次性”的,比如针对某个热点函数手工调整算法;有些优化是“可持续”的,比如在 prompt 里加了一条“禁止使用全局变量”,以后每次生成都会受益。
我建立了一个优化清单,分成三类:一次性优化、配置型优化、流程型优化。一次性优化靠人肉,配置型优化靠改生成器参数,流程型优化靠建立自动化检查。每次做优化总结时,都问自己一个问题:这个优化能不能沉淀到配置或流程里?如果能,就赶紧固化成模板或脚本。坚持一段时间后你会发现,需要人肉处理的问题会逐步减少,生成代码的初始质量会明显提升。这算是“优化”的优化,也是我带团队时最想强调的进阶心法。
6. 工具链与衡量指标:让优化工作看得见摸得着
6.1 静态分析与代码质量门禁
代码生成优化不能只靠肉眼,得靠工具把标准立起来。静态分析工具是我强烈建议的第一个环节。无论是 C/C++ 项目的 PC-lint、Cppcheck,还是通用代码的 ESLint、SonarQube,都能自动揪出潜在问题:未初始化变量、不必要的分支、复杂度超标、违反命名规范等。
以我常用的 C 代码生成项目为例,SonarQube 设了好几道门槛:圈复杂度低于阈值、重复率不能超过一定百分比、高危静态告警必须清零。生成代码提交前,先在本地跑一遍静态分析,不符合标准的直接重新生成或交给自动优化脚本处理。这里有个重要的经验:静态分析的规则模板不要全用默认,要根据项目实际调整。默认模板很多规则太宽松,对生成代码的约束力不够。我是基于生产事故复盘提炼出来的自定义规则集,精准很多。
编译告警同样不能放过。我要求团队把编译告警当错误看,特别是未初始化变量、隐式类型转换这类高危告警,出现一个就要处理一个。生成代码里这两种告警出现频率非常高,原因在于大模型对上下文类型推导偶尔不准确。早期我吃过这个亏,一个未初始化变量在特定输入路径下导致随机行为,排查了两天才定位。踏过这个坑之后,我把“零告警”作为提交的硬性要求,再没被这类问题坑过。
6.2 性能剖析与回归测试双轮驱动
性能优化的依据不能靠猜。第一步是用剖析工具找热点,把 CPU 时间片和调用次数最高的函数捞出来,再做针对性优化。perf、Valgrind、gprof、pprof这些都是我常用的,各有适用场景:perf适合运行时采样、Valgrind适合内存自动化检查、pprof适合 Go 项目的热点分析。选型不用贪多,抓住一个项目最核心的一两个工具,用熟用透比什么都强。
回归测试是优化的安全网。我见过有团队优化完代码后只跑功能测试,结果上线后数据量翻倍就崩了——原来是性能优化时改了缓存策略,却没有覆盖高并发的回归场景。一个成熟的回归测试套件应该有性能基准、容量测试、异常注入几个维度,每次优化后全量回归一遍,保证优化不会引入新的风险因子。这里有个小细节:性能基准的断言不要写死了,比如“某接口耗时不能超过 50ms”,如果底层服务器扩容或数据量变化,阈值就失真了。我建议做成比例式断言,比如“这次优化后耗时比基线下降 20%”,既真实又灵活。
6.3 量化优化效果:从玄学变成科学
优化效果要能量化,才能和“优化”“重构”这类模糊字眼拉开距离。我常用的量化指标有好几组,不同场景取不同维度。
针对通用代码,核心指标包括:接口平均延迟、P99 延迟、吞吐量、内存占用峰值、CPU 使用率、静态告警数量。针对嵌入式生成的 C 代码,我还额外关注:二进制体积、栈使用峰值、Flash 占用、执行周期数。针对大模型辅助业务代码,则会看:单位需求评审缺陷数、代码重复率、重构触达率、新增需求的平均开发耗时。这些指标不一定要全部监控,但至少要有一个“优化前后对比面板”。拿数据说话,优化工作在全球范围内的价值地位一下就清晰起来了。
我自己的经验是:把指标面板做成自动化产出的日报或周报,优化前后自动对比并标注变化幅度,比人工统计靠谱十倍。人也更愿意配合优化工作,因为结果一眼可见,价值感很强。
7. 常见问题与排查技巧实录
7.1 生成代码“优化后变慢”是怎么回事
很多人在实际工作中会遇到一个很反直觉的场景:明明做了优化,结果变慢了。我遇到过好几次,总结下来主要有三个原因。第一是“过早优化”:优化的对象根本不是热点,真正耗时的函数没动,优化产生的额外开销反而成了新负担。第二是“缓存副作用”:为了提速加了缓存,但缓存命中率极低,维护缓存带来的开销超过收益。第三是“编译器行为”:有些手工优化和编译器的自动优化方向冲突,反而干扰了编译器的向量化或内联决策,导致最终机器码劣化。
针对这类问题,我的排查习惯是:先跑剖析工具重新验证热点分布,不要假设上次优化前的热点位置现在还准;再检查优化代码是否引入了额外负担,比如多余的复杂度、缓存、加锁;最后做 A/B 对比编译,看看优化前后生成的汇编差异是否合理。这三个检查做完,问题基本能定位到根因。
7.2 “生成代码和模型对不上”怎么办
这个问题在 Simulink 模型生成代码场景中尤其常见。模型更新了,但生成代码没有同步,或者生成的代码和当前模型版本有出入,导致行为偏差或评审失败。
解决思路首先是建立“模型-代码一致性验证”机制:每次模型变更后,强制重新生成代码,并跑一遍差异对比,把模型版本号、生成的 hash 值、时间戳记录下来,随代码一起提交。这样一旦出问题,可以快速定位是哪次模型变更导致的不一致。其次是配置项要统一管理。很多生成工具的配置参数散落在开发者的个人环境里,这会导致同一个模型不同人生成结果不同。我会要求把生成配置做成共享的配置文件放进仓库,配合 CI 里的固定环境执行生成动作,确保输出可复现。
这个坑我在团队里反复强调过:配置不统一,等于每个人都在生成一套“私版代码”,维护成本高到让人崩溃。把它变成一种工程化流程,问题才能根治。
7.3 从大模型角度绕不出的“改一版又出 Bug”困局
用大模型辅助生成代码时,很多人会遇到一个经典循环:让模型改一个问题,它引入了两个新问题。原因在于模型对局部修改后的全局影响缺乏稳定的全局理解,尤其当代码块之间耦合度高时,简单修改很容易破坏隐性依赖。
我的应对思路是两条腿走路。第一,尽量把模块拆得足够独立,让大模型一次只改一个模块,降低耦合性带来的风险;第二,每次让模型修改前,先把完整的上下文喂给它——包括相关模块的接口定义、依赖关系、调用链说明,不要只给它一个“改这里”的孤立指令。另外,每次修改后都跑一遍完整的回归测试,不要只测改动的模块,因为回归测试是捅破“改一版又出 bug”循环最直接的工具。
还有一个小经验:给大模型设置“修正边界”。在 prompt 里明确告诉它“请只在函数 X 内部修改,不要改动其他函数”,能显著降低大模型“顺手改了不该动的地方”的概率。这个技巧我到现在还在用,效果一直很稳。
8. 写在最后的实操心得
做了这么多年的代码生成优化,我个人的体会越来越清晰:这项工作的核心不是“把代码改漂亮”,而是“建立一个让生成结果可控、可预期、可持续改进的流程”。不管是 Simulink 生成的嵌入式代码,还是大模型辅助的业务代码,优化动作本身只是一个入口,真正值钱的是背后成套的方法论和工程化能力。
最后再分享一个小技巧:每次做完一轮优化,我都会把“这个优化的套路能不能固化成模板或脚本”当作复盘的第一问题。能固化的尽量固化,不能固化的至少写成团队 Wiki。坚持大半年之后你会发现,生成代码的基线水平肉眼可见地提升,需要救火的情况越来越少。这比任何一次惊艳的优化效果都更值得追求。