前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9831
  • 用4个AI agent协作开发RAG框架:真实工程踩坑记录
  • Anthropic 发布终端编程 Agent Claude Code
  • Karpathy 出品:让 Claude Code 少犯错的指南
  • OpenAI 推出终端编程 Agent Codex CLI
  • AI写量化策略的四个坑:别让AI替你做风控决策
  • 四大Agent开发框架对比:各有所长,各有取舍
  • Agent知识管理:为何结构化Wiki比向量检索更可靠
  • 2026年开源AI编程工具全景图
  • 16节点扩张至36节点DGX Spark集群:家庭实验室AI推理实战
  • Claude Code/SDK/MCP/API四层对比:选型指南
  • 微软Skill Recorder评测:做演示让AI学会操作技能
  • Claude Code新增Design预览:命令行直接生成可编辑UI草稿
  • Claude API 多 Agent 流水线在生产环境的可靠实践
  • reflint:检测 AGENTS.md 引用的路径是否已失效
  • LLM模型中迁移学习的实战:用提示实现领域适应
  • Agent 循环的停止条件设计:如何写可验证的「完成」标准
  • Muse Glimmer 30B 实测两周:社区发现官方 benchmark 没说的坑
  • K8s RBAC 正确姿势:为 AI Agent 配最小权限 ServiceAccount
  • 英伟达通知明年AI服务器涨价超15%,因内存成本飙升
  • AI Agent安全防护:模型资产与API防泄露实战指南
  • 免费模型通过全部单元测试,复杂度曲线暴露O(n²)性能陷阱
  • Inherent 发布 Faraday:小模型科研复现超越 GPT-5.5
  • 270亿参数模型复现科研论文超越GPT-5.5,Inherent开源研究智能体方法
  • 编码Agent横评:同任务同模型,节省40%调用成本
  • 企业级 LLM 应用安全指南:NeMo Guardrails 实战
  • AI 编码代理防坑指南:先澄清意图再动手
  • 自托管LLM五年TCO成本指南
  • AI研究agent在股票暴跌时撒了谎——对抗测试揭示使用边界
  • Gemini 3.7 Flash发布:编程基准分数大幅跃升
  • 我用18条AI预测做记分牌:行业大佬的命中率惨不忍睹
  • Agent开发的核心失败:聊天窗口不是好架构
  • AI 组件防御提示词注入:结构化分离与实现模式
  • EU AI Act 透明度条款已生效,你的开源项目也在管辖范围
  • Pydantic AI多步Agent存在O(n²)历史膨胀开销
  • 为AI Agent配置熔断和终止开关防止API预算超支
  • Google EnvHarness:为Agent环境引入可编程适配层
  • 通过MCP将开源编程Agent接入真实工作流
  • 内部检查全过但交接仍错误的根因分析
  • 为欧美后端选型文本分类API的实战方法论
  • 测试LLM后端时如何避免API调用烧钱
  • Edtech API多租户LLM供应商的五项结构化测试
  • 微软Agent Optimiser原理与工程价值
  • 编程任务LLM vs 通用任务LLM的架构差异
  • 免费模型服务器并发测试:16 并发时崩溃
  • 生产级客服聊天机器人的架构与选型
  • Claude/Codex用量追踪实战:任务归属与成本核算的边界问题
  • Linus Torvalds自述:AI辅助调试Linux内核的真实体验
  • 浏览器端具身AI物理仿真基准:Rapier/WASM实现零部署评测
  • Claude、Codex、Gemini同题PK:盲评实验揭示编程能力差异
  • AI 编程工具真实增效数据:研究综述与选型建议
  • 为 AI Agent 构建基于能力的安全层:架构实现解析
  • 已加载 51 / 9831
8.0
热点
AI SCORE
技术实践2026-08-23 08:38

免费模型通过全部单元测试,复杂度曲线暴露O(n²)性能陷阱

dev.to · AI#AI代码审查#性能优化#复杂度分析
Editor brief · 编辑速览

某免费模型生成的C++哈希表通过了42个单元测试和 sanitizer,却在10万条插入中耗时4.2秒——复杂度曲线揭示了O(n²)碰撞问题,一轮修复解决。提示测试正确性不等于性能正确性。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

单元测试证明了正确性,但没有证明复杂度。这不是一个关于测试失败的故事,而是一个关于代码仍有缺陷、测试却全部通过的故事。

在本次案例研究中,一个免费模型的 C++ 哈希表通过了全部 42 个单元测试和两个 Sanitizer 工具,然后在插入 100,000 个真实键时耗时 4.2 秒。扩展曲线在三组数据中暴露了 O(n²) 的碰撞模式。修复只花了一轮。

我使用 MonkeyCode 的免费模型访问生成第一版代码,并在其免费服务器选项上运行验证门控,因此整个过程中编译器、编译参数和环境保持完全一致。声明:本文是 MonkeyCode 产品推广的一部分。

我需要一个用于日志去重工具的小型字符串键映射。热路径读取一行,提取类似 2026-08-23T10:15:30 node=7 seq=000123 这样的键,然后对唯一键计数。映射表就是性能瓶颈。

需求很明确:C++17,仅此而已,无外部依赖,分摊后 O(1) 的插入预期,以及 100,000 次插入在 100ms 内完成。最后一条需求是一份复杂度契约,而非风格偏好。

验收标准如下:

AddressSanitizer 和 UndefinedBehaviorSanitizer 无任何报告。

插入 100,000 个结构化键在 100ms 内完成。

第三条标准是大多数验证流水线都会遗漏的一项。本案例研究要回答的就是:为什么遗漏这一项代价高昂。

模型生成的是一个使用 2 的幂容量的链式哈希表。结构中规中矩,但哈希函数不是:

size_t hash(const std::string& key) const {
    size_t h = 0;
    for (size_t i = 0; i < key.size() && i < 4; ++i) {
        h = (h << 8) | static_cast<unsigned char>(key[i]);
    }
    return h & (capacity_ - 1);
}

键只有前四个字节参与哈希运算。插入路径看起来没问题:

void insert(const std::string& key) {
    size_t idx = hash(key);
    for (auto* node = buckets_[idx]; node; node = node->next) {
        if (node->key == key) return;
    }
    buckets_[idx] = new Node{key, buckets_[idx]};
    ++size_;
}

我的日志数据中每个键都以 2026 开头。它们全部哈希到了同一个桶。每次插入都在扫描一条不断增长的链表。

我按顺序跑了三个阶段。第一阶段是带警告和 Sanitizer 的编译:

g++ -std=c++17 -Wall -Wextra -O1 -fsanitize=address,undefined -o map_test map_test.cpp
./map_test

全部 42 个单元测试通过。ASan 和 UBSan 默不作声。第二阶段是扩展性基准测试:

#include <chrono>
#include <iostream>
#include <string>

int main(int argc, char** argv) {
    const size_t n = std::stoull(argv[1]);
    StringMap map;
    auto start = std::chrono::steady_clock::now();
    for (size_t i = 0; i < n; ++i) {
        std::string key = "2026-08-23T10:15:30 node=7 seq=" + std::to_string(i);
        map.insert(key);
    }
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                  std::chrono::steady_clock::now() - start)
                  .count();
    std::cout << n << " " << ms << "ms\n";
}

第三阶段是决策规则。我在 N、2N 和 4N 下运行基准测试,然后比较比值:

for n in 25000 50000 100000; do
  ./map_bench "$n"
done

第一次运行得到:

25000  262ms
50000  1048ms
100000 4197ms

输入翻倍,时间变为四倍。这就是 O(n²) 的特征,仅凭三个数字就能看出来。不需要 Profiler,不需要火焰图,不需要猜测。

我把扩展表反馈给模型,只加了一条指令:哈希必须使用整个键。第二个版本用 std::hash<std::string> 替换了手写的哈希函数:

size_t hash(const std::string& key) const {
    return std::hash<std::string>{}(key) & (capacity_ - 1);
}
25000  9ms
50000  19ms
100000 38ms

输入翻倍,时间也翻倍。同样的 42 个单元测试仍然全部通过。正确性没有任何改变。第一版代码是正确的,同时也是不可用的。

我现在使用的规则是:如果 time(2N) / time(N) 高于 3,就停下来检查算法,在此之前不动任何东西。比值接近 2 意味着线性。接近 4 意味着二次。基准测试耗时约一秒,替换掉的是数小时的猜测。

首先,测试全绿不是性能通行证。42 个单元测试使用的是 alpha 和 beta 这样简短的、不同键名的键。它们的前四个字节各不相同,因此分散到了各个桶中。测试从未模拟过生产数据会产生的分布。

其次,扩展性基准测试是我所知道的最便宜的复杂度检测器。三次运行、一个 shell 循环、一个比值。它发现了一个 Sanitizer、警告和看起来正确的代码审查都漏掉的缺陷。

第三,环境很重要。我在 MonkeyCode 的免费服务器选项上运行了每个阶段,这意味着编译器在每轮中完全一致。如果基准测试在我的笔记本电脑上运行,热节流可能以错误的原因产生相同的 4x 比值。

第四,修复不是重写。只是给哈希函数改了一行代码。模型的结构是合理的,只是分布被破坏了。这是一种常见的失效模式,而且捕获成本很低。

本案例研究范围狭窄。前缀哈希缺陷只在键共享前缀时出现。随机键或短键可能永远不会触发它,这意味着在大多数时候这个门控看起来并不必要,直到某一天它突然变得必要。

不要对只读工作负载、固定字典的场景使用这个方案。带二分查找的有序向量会击败任何哈希表,不管是生成的还是手写的。不要在需要线程安全的地方使用生成的哈希表;这个是单线程设计的。

免费服务器选项是一个验证环境,不是生产主机。我用它来门控代码,而不是提供服务。一个小的 C++17 项目并不是对免费模型的通用判决。可复用的产物是方法:编译、Sanitize、扩展、决策。

如果你在生成的代码上运行了类似门控,把扩展曲线发给我。我想要的是形状,不只是通过/失败。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
AI Agent安全防护:模型资产与API防泄露实战指南
下一篇
Inherent 发布 Faraday:小模型科研复现超越 GPT-5.5