ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

37%准则:用最优停止策略破解优化决策难题

37%准则:用最优停止策略破解优化决策难题 我前阵子接手一个线上服务接口吞吐上不去团队里每个人都有一套“我觉得应该这样调”的方案。有人提议先梭哈全量参数搜索有人主张凭经验直接改慢SQL还有人想先把所有候选项都试一遍再决定。吵到最后一个做运筹的老同事丢了一句你们这就是秘书问题先看37%后面看到更好的就直接换。我后来才发现这句话比大部分优化方法论都管用。它背后就是那个常说的37%准则也叫最优停止规则。用一句话描述当你在一组有序、逐个出现的候选项里做选择只能选一次不能反悔那就先观察前37%的候选但不做选择只记录其中最优值之后一旦碰到超过这个阈值的候选立即选它。这个策略能让你在不知道候选池总体分布的情况下以最大概率选到最好的那个长期赢面约37%。这个准则对我的意义在于它给“优化”这件事提供了一个具体可执行的决策边界。我们做性能优化、SQL调优、参数寻优、甚至日常方案选型绝大多数时间不是缺方案而是缺一个“什么时候该停手、什么时候该出手”的判断标准。37%准则恰好填上这个空。这篇文章就把我从原理到实操、再到踩坑和心态调整的完整经验写出来希望对正在做优化、调试、选型的朋友有参考价值。1. 什么是37%准则一个被低估的决策工具1.1 从秘书问题说起一个困扰数学家百年的选择题秘书问题最早是20世纪60年代在统计学界流传的一道理想化难题一项一项面试秘书候选人每面完一个就必须立刻决定是否录用不能回头联系之前的候选人假设n个候选人随机到达你只知道人数n不知道每个人的综合水平排序请问如何决策才能最大化选到全体的最优者的概率这个问题的难点在于“在线决策”没有上帝视角不能先看完全部再挑因为拒绝即丧失机会。它的本质是探索和利用的权衡看太少基准不可靠看太多好机会被错过。数学上已经证明最优策略就是把前约37%的候选当作纯观察样本记录其中最好的那个作为基准线之后遇到第一个优于基准线的候选立即录取。成功率随n增大趋近1/e约36.8%。所以叫37%准则。实际优化场景跟秘书问题几乎一模一样。比如你要给一个推荐系统调超参数候选参数组合可能有几十组受时间和算力限制你不可能全跑完每跑一组都要花小时级成本跑完不选等于浪费。这种情况就可以用37%准则设计一个“先观察、后出手”的搜索顺序。再比如慢SQL优化候选的索引方案、改写方案可能列出来很多但压测一次要重启服务、刷数据成本不低盲目全量验证非常奢侈。但这里必须说清楚一个前提秘书问题是一个理想化模型不是万能药。它给出的不是“最优结果”而是“最优策略”。这句话我是在实际写过很多行优化代码之后才真正体会到的一个好的决策流程不等于每次都能选出最好的选项而是长期来看赢面最大。37%准则的价值恰恰在于它可以执行、可以重复、可以解释而不是让你拍脑袋赌运气。1.2 37%这个数字到底怎么来的这部分数学推导我尽量用大白话讲不堆复杂公式但建议你至少看懂一次因为看得懂才敢在实操里用它。假设总候选数n策略是前k个一律不选只记录最大值M从第k1个开始如果某个值大于M立刻选择它停止。问题是k取多少时选到全局最优的概率最大。选到全局最优意味着两件事同时成立全局最优出现在位置i而且i大于k同时从第k1个到第i-1个位置上的值必须都小于M。换句话说全局最优出现之前不能被基准M拦住。当n很大时可以近似处理最优出现在位置i的概率是1/n在i之前前k个里最大值M要超过中间所有值。计算下来的总概率近似为 (k/n) * ln(n/k)。令tk/n这个式子变成 t * (-ln t)。对t求导令导数为0得到 -ln t - 1 0即 t 1/e约0.3679。所以观察比例取全部候选的约37%是数学上的最优值。我用一个更直观的比喻解释你在一段时间内不断遇到选项如果一开始就做决定基准太低后面大概率后悔如果拖到最后优秀选项早就错过了。37%就是这两个错误的平衡点。就像爬山时你不知道最高峰在哪最稳的做法是先花37%的时间确认“这一路起码有多高”之后一旦爬到比这个高度还高的地方就认定这是你当下最好的决定之一。这个推导还有个有意思的推论37%准则不依赖候选数量n的具体大小只依赖“候选的顺序是随机的”这一假设。这意味着在不知道n的精确值、只知道一个大概范围的情况下也能用只要观察比例对就行。我在实际项目里遇到过候选池数量只能估个大概的情况按37%的比例走结果依然可用。1.3 为什么它天然适合“优化”语境我观察到一个现象很多做优化的人其实不缺方法缺的是停止规则。比如慢SQL优化DBA给你列了十几种索引方案、改写思路你逐一试试到中间觉得已经不错了但忍不住继续试结果时间全耗在“万一还有更好的呢”上。这就是典型的探索过度。37%准则正好提供一个决策框架把方案池量化先验证前37%记录当前能达到的最优水平此后一旦出现超过这个水平的方案就果断收敛。这样既不会因为急着下单而错过明显更好的选项也不会因为贪心下钻而无限拖延。而且它特别适合那些“验证成本高、候选池有限、不能回溯”的场景。比如数据库索引调整每次验证要重新建索引、跑压测比如硬件选型试完一个再换一个要重烧配置比如产品A/B实验线上实验有流量成本开了两个版本之后想回头再跑旧版本用户已经用完就回不来了。这些场景下37%准则可以用一张简单的表格、一个计数器就落地不依赖复杂的机器学习模型。另外热词里经常出现的“成本优化”“样本效率优化”“并行sql优化”“移动端性能优化”等概念背后其实共享同一个母题在有限预算和无限可能性之间做取舍。37%准则把母题用一个清晰的数字边界落下来这是它能跨领域复用的原因。理解了这个底层逻辑你再看后面几节的具体操作会发现它们只是同一套决策框架在不同场景下的变体。2. 用37%准则解决调优中的“探索-利用”困境2.1 调参寻优的探索-利用矛盾做机器学习的人对探索-利用这个矛盾都不陌生。exploitation是继续压榨当前最优解exploration是花预算去尝试新方向。网格搜索、随机搜索、贝叶斯优化本质上都在处理这个矛盾只是策略不同。37%准则属于最简单的离线策略先纯探索一小段再转纯利用。它不像贝叶斯优化那样有复杂的代理模型不需要维护协方差矩阵也没有采集函数。它只要求你定义候选方案的顺序确定一个可以量化的指标设置停手阈值。就这三件事没了。有一次我做向量数据库集成与优化候选方案包括不同的索引类型、不同的归一化方式和批量查询参数加起来二三十种组合。按单次压测5到10分钟算全测完要三四个小时。我用37%准则先随机排列这些组合测前约30%的组合并记录最好成绩然后从第31%开始挨个测只要发现一个刷新记录的组合立刻切过去做深度压测不再回头看剩余方案。整个流程控制在1小时多一点最终线上用的就是那次命中方案之一。当然这不代表它一定比全量搜索更优全量搜索在预算足够时当然更稳妥。我强调的是预算受限时37%是性价比很高的决策方式它用可接受的次优概率换掉了大量验证时间。对工程团队来说时间往往比那一点点理论上的最优更值钱。2.2 让理论落地一个SQL慢查询优化案例用“慢sql优化”“mysql 怎样优化”这些热词出现的高频场景我拆一个具体案例看看37%怎么接进SQL优化流程。假设你有一批慢查询DBA和技术负责人一起列了6条优化策略给WHERE条件字段加单列索引调整联合索引顺序改写成覆盖索引查询拆分大查询改成分页或批处理优化表结构去掉冗余字段和类型不匹配引入缓存把高频查询挡在数据库外面。这是典型的“候选池有限、验证成本高”场景。乱序执行时很多人会从最简单的加索引开始如果恰好效果很好就一直用如果效果不好就会陷入“是不是方法不对”的自我怀疑反复重试同一个方案浪费大量时间。用37%准则候选池n6观察数kceil(0.37*6)3前3个方案只测不选记下这3个方案里表现最好的是什么比如方案3把某条查询从120ms降到40ms记为基准M。从第4个方案开始每测一个只要新成绩优于40ms比如方案4跑到35ms或方案5跑到30ms就立即收手用这个方案做最终优化不再测试剩余候选。这里有个很微妙的地方由于观察数是ceil(0.37n)当n6时k3实际上从第4个开始决策。如果第4个方案没有超过基准要不要继续按算法应该继续测第5、6个一旦超过就停如果一直没超过就退回观察期里的最优值。这是一种“保底”策略即使后面都没刷新记录你至少不会比前k个里最好的差。实操中我还会加一个“1.1倍奖励线”只有超过基准的10%以上才算“明显更好”否则认为差距在噪声范围内不触发切换。因为压测有抖动40ms和38ms的差异可能只是网络波动不是真实优化提升。这个细调很重要后面我会专门讲。2.3 注意不是所有参数搜索都适用37%准则37%准则有前提条件很多人拿起来就用结果翻车。我在实际使用中总结了三个不适用场景。第一候选指标存在强噪声时需要先降噪。如果每次验证的指标波动超过10%到20%37%的观察期可能无法建立可靠基准。解决办法是每组验证重复3次取中位数或者调整奖励线避免因为随机波动触发选择。第二候选项目之间存在强相关性时观察期记录的最优值可能只是“局部最优”。比如你在调某一个超参数候选值之间差异很小且目标函数的梯度方向一致前37%落在梯度中间基准偏低后面刷新记录的可能性很大37%的“停手”判断就会过早。这种场景更适合用贝叶斯优化或贪婪爬山不是37%。第三候选顺序不能是“人为挑过的”。37%的数学保证建立在随机顺序上。如果前37%恰好是你有意挑选的最差组合基准虚低后面很容易触发选择但选到的也可能只是中等方案如果前37%恰好是最好组合基准虚高后面很难刷新记录你会一直测到结束浪费预算。实操里尽量打乱顺序或使用随机化抽样。判断一个场景适不适合我一般问自己三个问题验证一次的成本高不高候选数量是不是有限且可以枚举能不能做到顺序随机化三个都回答“是”就用37%只要有回答“否”就要考虑替代方案。3. 实操模板手动优化项目的三阶段流程这一节我把37%准则落到一个可以“照抄”的模板上。无论是做代码性能优化、SQL调优还是做成本优化、向量数据库集成优化都可以套这个流程。模板分三个阶段。3.1 阶段一划定候选池与观察期第一步把所有候选方案明确列出来并编号。这一步看起来简单但很多人做不好因为总是“边想边试”候选池不断膨胀观察比例就失真了。我建议先用文档把所有候选定死中途除非出现全新的类别否则不加项。第二步决定观察数量k。公式是kceil(0.37*n)n是候选数。列个常见值方便参考n5k2n6k3n8k3n10k4n14k6n20k8。比如n10观察期就是前4个候选。注意观察期里不是“什么都不做”而是认真测、认真记录只是不承诺使用它们中的任何一个。它等价于一个勘探期目的是校准你对“好效果”的判断。第三步确定一个单一量化指标。这是整个流程里最容易翻车的环节。指标一定要和业务目标强相关而且可重复测量。比如慢SQL优化用p95耗时成本优化用单位请求成本模型调优用验证集上的AUC移动端性能优化用冷启动耗时下降率。一个项目只允许一个主指标其他指标仅供参考否则无法执行“谁超过基准就停”的规则。第四步随机化顺序。用随机数生成器对候选集合排序。千万不要为了让“看起来合理”而手动排序。手动排序通常会把最熟悉、最有把握的方案放前面这会破坏随机性后面分析时你没法确定37%准则是起作用了还是仅仅因为你的先验。3.2 阶段二用前37%建立基准按随机化后的顺序依次执行前k个候选方案每个方案都跑完整验证流程记录指标。前k个做完后取这k个样本里的最优值作为基准M。这里有一个容易被忽略的点基准M要保留“当时的环境快照”。比如你测的是SQL优化记录最优方案的同时要记下它的执行计划、当时的数据量、慢日志中的原始耗时。否则等你测到第5个方案时数据分布变了比较就不公平了。实操中我会额外维护一个小表记录每个候选方案的序号、方案描述、指标值、环境备注、结论。表格示例序号方案简述主指标环境备注是否优于基准1观察期加单列索引120ms数据量100w行观察期不决策2观察期联合索引调整80ms数据量100w行观察期不决策3观察期覆盖索引改写55ms数据量100w行基准M55ms记录快照4拆分大查询40ms数据量100w行超过基准触发选择观察期结束后你的任务是“只看不选”。很多新手一看到第2个方案效果不错就想提前用这会让整个策略失效。忍住。前37%的意义就在于校准认知而不是产出最终结果。这一点我在带新人时反复强调也确实是新人最容易犯的错误。3.3 阶段三一旦越过阈值就立即行动从第k1个候选开始按顺序依次验证。每验证一个与基准M比较。如果出现某个方案指标优于基准M立即停止测试选择该方案作为最终优化结果如果验证完所有剩余候选发现都没有超过基准则回退使用观察期中的最优方案M。这个“回退”机制很关键它保证了37%策略的最坏结果不会差于观察期最优而不是让你空手而归。很多人理解秘书问题时只记住了“看到更好的就选”却忽略了“实在没有更好的就用基准”这个保底动作。触发选择之后是否需要对选中的方案再做额外验证我的建议是要。因为37%准则本身只是决策规则不是质量验证工具。选中的方案必须再过一遍完整回归测试确认在更大数据量、并发场景下依然达标。相当于你在“选型”阶段用了37%策略在“落地”阶段仍然使用常规的回归、压测、灰度发布流程。我在一个移动端性能优化项目里就用过这个模板。候选方案一共有9项n9kceil(0.37*9)4。前4项里有1项把冷启动耗时从1.8秒降到1.2秒记为基准第5项只到1.3秒未超过第6项到1.1秒立即触发选择。剩余3项直接不再测试节省了约一半的验证时间。最终上线版本的冷启动耗时是1.09秒过程中没有陷入无休止的方案对比。4. 典型误用场景与避坑清单37%准则看起来很简洁一旦用错结果可能比凭直觉还差。我把常见的误用归纳成四类每一类都对应我真实踩过的坑。4.1 误用一把37%当作固定“最优”而非阈值点很多介绍里会把37%描述成“选择前37%里最好的”这个表述不准确会让人误解成“永远只选第37%个”或“只在前37%里挑一个”。准确的说法是前37%是观察期真正做决定发生在后63%。决策点不是固定的第37个位置而是“观察期之后第一个超过基准的位置”。我用一个例子说明如果候选数n20k8。观察期是前8个但选择可能发生在第9个、第15个或者第20个不一定在第8个。如果第9到第20个都超不过基准则最后回退用第1到第8个里面的最优。所以37%不是“你只能选第8个”而是“前8个必须看完之后随时可以停”。在实操中这种理解差异会带来两个行为上的变化一是你不会在观察到第8个后急急忙忙决定而是继续按顺序测二是你会保留“全部测完都没更好”的预案不会因为没有触发选择就慌乱。4.2 误用二忽略“观察顺序”的随机性37%的推导假设候选按随机顺序到达。如果顺序是人为安排的结论不成立。我见过一个团队做数据库优化把“最可能有效的方案”放在最前面测结果前37%全是最优的几个基准非常高后面怎么测都超不过最后浪费了两天时间。正确做法是生成随机序列并且把这个随机序列记录下来。随机化听起来反直觉尤其在你对候选方案有很强先验时。但你想一下如果你的先验真的足够可靠根本不需要用37%策略直接选最优方案就行既然选择用策略说明你没有足够把握那顺序就必须交给随机性。如果候选池里混合了多类方案还想保持随机化建议使用分层随机按方案类别分层在每层内随机排列再交替取序。这样既保留随机性又避免某一类方案扎堆出现在观察期导致基准偏向某类技术。4.3 误用三样本数量过小时硬套公式n很小时37%策略的效果会退化。比如n2kceil(0.37*2)1策略是看第一个不选第二个若比第一个好就选否则回退选第一个。它总能选到两个里更好的吗不是如果第一个就比第二个好回退选第一个结果是很好的如果第二个更好也能选到第二个。所以n2时这个策略其实是100%选到最优。但这是边界特例不能证明策略总是有效。n3时k2策略是前两个不选第三个若比两者都优就选否则回退到前两个的最优。这样选到全局最优的概率取决于顺序不一定总是最优。所以你看到n越小套公式的误差越大。我的建议是候选数至少6到8个再使用37%小于6个就直接全量验证反正验证成本低。候选数过大也有问题比如n5000时前37%就是1850个观察成本太高这时更适合先做粗粒度筛选把候选压缩到50个以内再套37%准则。4.4 常见问题排查速查表我整理了一个常用排查表覆盖实操中的主要问题问题可能原因对应的解决方案触发选择后效果不如预期验证环境不一致或指标噪声大建立环境快照重复3次取中位数观察期基准过高后面难触发顺序非随机或基准恰好是全局最优重新随机化或分层随机化观察期基准过低过早触发前k个恰好最差接受概率或增大k到ceil(0.4n)但要明白偏离1/e会降低成功概率候选池中途膨胀边想边加方案预先固定候选池新方案进入下一轮优化周期指标维度太多难判断主指标不唯一选一个和业务目标最相关的指标做主指标每次压测结果波动大未做重复实验、系统资源竞争先跑基准预热再加控噪机制这张表是我实践过程中踩坑总结出来的并不复杂但每一条背后都对应一次真实的浪费时间。有一个特殊场景要单独提醒如果你做的优化是“成本优化”比如云资源成本优化候选池往往不是离散的几个方案而是连续的资源配置参数。连续空间下37%准则的“枚举候选”前提不成立你需要先把配置参数离散化成若干档位比如CPU核数取2、4、8、16内存取4G、8G、16G或按量付费和包年包月等再做候选池。不要试图在连续区间里用“下一档更优就停”的策略那会陷入局部最小值。5. 从37%出发我对优化决策的几点心态建议5.1 选择焦虑的根源做优化的人往往有一种隐性焦虑担心错过更优方案。这种焦虑消耗的时间可能比真正做优化的时间还多。我见过一个运维同事优化批处理任务从2小时优化到40分钟已经远超业务要求但因为网上有人说还能优化到15分钟他又花了两周调参最后只降到30分钟收益严重递减。37%准则在心态上给我的解放在于它承认“你无法保证选到最优”只保证“在长期重复使用这个策略的情况下你的赢面最大”。这不是安慰而是数学结论。一旦接受这个设定你就不会在每次决策中都要求自己“必须选出最好”而是要求自己“按照正确的流程做决策”。流程对了结果哪怕不是最优也是可以接受的次优。这跟写代码是一个道理你不能保证你写的每个接口都没有bug但只要你保证测试流程健全、review流程到位长期来看你的代码质量一定高于靠个人感觉堆出来的代码。5.2 用最小代价换取可接受结果优化工作天然有预算约束。人力资源、机器资源、时间窗口、业务容忍度每一项都是有限的。37%准则在预算约束下提供了一条量化路径让你能向团队解释“为什么在这里停手”。举例一次优化任务全量验证需要40小时用37%策略可能只需要20小时。如果你告诉团队“我们用37%准则做决策理论上约有37%概率选到全局最优其余情况也能拿到观察期最优作为保底”这比“我觉得应该够了”有说服力得多。但注意别把这句话变成口号它只是一个决策解释工具。对于成本优化这种长期项目我还会把37%准则当做“单轮优化周期”的决策规则每轮周期列候选方案按37%收窄产出本轮结论下一轮再补充新的候选方案。这样优化不是一次性动作而是持续迭代的过程。每一轮都不追求极致但多轮下来整体趋势不断提升这比一轮死磕到最优更符合工程实践。5.3 一个扩展思考从最优停止到成本优化我最后想聊一个更广义的延伸。37%准则的本质是最优停止理论在有限信息场景下的特例。其实很多优化问题都可以看作“何时停止”的问题慢SQL优化到什么程度可以上线A/B实验要跑多久才能出结论模型训练中该在哪个epoch早停线上缓存命中率到多少就可以不考虑进一步调整这些问题没有一个统一的答案但最优停止理论给了我们一个共同的分析框架分析单次验证成本、候选或迭代的总预算、结果的波动性然后确定一个停止规则。有时候停止规则是“连续5轮无提升就停”有时候是“超过历史最优的1.1倍才切换”有时候就是朴素的37%。我的体会是37%准则不一定每次都是全局最优决策方法但它足够简单、足够透明容易让团队达成共识。相较于黑箱的优化算法它更像是一个可以写在纸面上的决策契约大家事先约定观察期多长、基准怎么取、触发条件是什么。这种契约带来的效率提升有时比策略本身的数学收益更大。最后分享一个我至今还在用的小习惯每次开始优化项目之前我会把候选方案列表、观察数量、基准指标、触发条件和保底方案写进一个短暂的文档或注释测完后回头对比。这样既监督自己不偏离决策规则也为下一次优化积累数据。实践久了你会发现真正稀缺的往往不是更好的优化技巧而是一个敢在合适时机停下来的决心。
返回列表