当代码存在性能问题、执行缓慢、内存占用过高、嵌套循环过多、超时错误(timeout errors)、TLE(Time Limit Exceeded),或未能通过性能基准测试时,请使用本工具。 同样适用于算法复杂度分析、数据结构优化,或当用户提及 Big O、O(n²)、时间/空间复杂度、性能调优(performance tuning)、优化(optimize)、加速代码(speed up code)等场景,支持 C++、Java 和 Python。
代码优化器 技能是一项面向实际任务的技能,主要用于转换代码, 既减少时间和空间复杂度, 同时又保持正确性;聚焦到 C++, Java, 和 Python 的验证优化模式;
该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
在保持功能正确性的前提下,重构代码以降低时间与空间复杂度。重点关注 C++、Java 和 Python 中已被验证的优化模式。
核心原则:可量化地改善复杂度,并验证行为未发生变更。
适用于所有与性能相关的工作:
尤其适用于以下情况:
| 症状 | 潜在问题 | 快速修复方案 |
|---|---|---|
| 对同一数据集进行嵌套循环 | O(N²) | 哈希表或双指针 |
| 在无序列表中执行查找 | 每次查找 O(N) | 转换为 set / hash |
| 在循环中拼接字符串 | O(N²) 内存抖动 | StringBuilder / reserve |
| 重复排序 | 每次排序 O(N log N) | 仅排序一次,缓存已排序结果 |
| 递归爆炸 | 指数级复杂度 | 记忆化 / 动态规划 |
| 未预分配容量的 vector 扩容 | 多次内存分配 | 预先调用 .reserve(N) |
每次优化均须严格遵循以下步骤:
优化进度: - [ ] 步骤 1:识别当前复杂度 - [ ] 步骤 2:分析瓶颈来源 - [ ] 步骤 3:选择优化策略 - [ ] 步骤 4:实施最小化变更 - [ ] 步骤 5:验证复杂度是否改善 - [ ] 步骤 6:确认行为未发生变化
步骤 1:识别当前复杂度
步骤 2:分析瓶颈来源
| 模式 | 典型瓶颈 |
|---|---|
| 对同一数据集进行嵌套遍历 | 双重循环导致 O(N²) |
| 在无序列表/数组中查找 | 每次查找 O(N) |
| 重复排序 | 每次排序 O(N log N) |
| 在循环中拼接字符串 | 因重复拷贝导致 O(N²) |
| 未使用记忆化的递归 | 指数级分支展开 |
| 在循环中创建大型对象 | 内存压力 + GC 开销 |
步骤 3:选择优化策略
参见下方「算法选型决策树」。
步骤 4:实施最小化变更
步骤 5:验证复杂度是否改善
步骤 6:确认行为未发生变化
digraph algorithm_selection {
rankdir=TB;
"Nested loops identified?" [shape=diamond];
"Lookup operation?" [shape=diamond];
"Hash Tablen(O(1) lookup)" [shape=box, style=filled, fillcolor="#ccffcc"];
"Range query?" [shape=diamond];
"Tree/Heapn(O(log N) query)" [shape=box, style=filled, fillcolor="#ccffcc"];
"Sliding pattern?" [shape=diamond];
"Two Pointers/Windown(O(N))" [shape=box, style=filled, fillcolor="#ccffcc"];
"Subproblem reuse?" [shape=diamond];
"DP/Memoizationn(Polynomial)" [shape=box, style=filled, fillcolor="#ccffcc"];
"Ordering needed?" [shape=diamond];
"Pre-sort oncen(O(N log N))" [shape=box, style=filled, fillcolor="#ccffcc"];
"Keep nested loopsn(document constraint)" [shape=box, style=filled, fillcolor="#ffcccc"];
"Nested loops identified?" -> "Lookup operation?";
"Lookup operation?" -> "Hash Tablen(O(1) lookup)" [label="yes"];
"Lookup operation?" -> "Range query?";
"Range query?" -> "Tree/Heapn(O(log N) query)" [label="yes"];
"Range query?" -> "Sliding pattern?";
"Sliding pattern?" -> "Two Pointers/Windown(O(N))" [label="yes"];
"Sliding pattern?" -> "Subproblem reuse?";
"Subproblem reuse?" -> "DP/Memoizationn(Polynomial)" [label="yes"];
"Subproblem reuse?" -> "Ordering needed?";
"Ordering needed?" -> "Pre-sort oncen(O(N log N))" [label="yes"];
"Ordering needed?" -> "Keep nested loopsn(document constraint)" [label="no - inherent O(N^2)"];
}
决策说明:
| 决策 | 条件 | 策略 | 效果 |
|---|---|---|---|
| 哈希表 | 需频繁执行查找操作 | 将列表查找替换为 set / map | O(N) → O(1) 每次查找 |
| 树 / 堆 | 需支持最小值 / 最大值 / 区间查询 | 采用有序数据结构 | O(N) → O(log N) 每次查询 |
| 双指针 | 存在连续区间模式 | 用双指针替代嵌套循环 | O(N²) → O(N) |
| 动态规划 / 记忆化 | 存在重复计算的子问题 | 缓存子问题结果 | O(2^N) → O(N) 或 O(N²) |
| 预排序 | 排序后可简化逻辑 | 仅排序一次,利用有序性 | 视具体场景而定 |
| 反模式 | 检测信号 | 影响 | 修复方式 |
|---|---|---|---|
| 循环内对列表执行查找 | in list 出现在 for 循环内部 |
O(N²) | 改用 set() |
| 循环内拼接字符串 | 循环中对字符串使用 += |
O(N²) 内存开销 | 改用 StringBuilder |
| 未预留容量的增长操作 | 仅使用 push_back / append |
多次内存分配 | 显式调用 .reserve(N) |
| 循环内重复排序 | sort() 出现在循环内部 |
每次排序 O(N log N) | 移至循环外,仅排序一次 |
| 递归爆炸 | 存在递归调用且无记忆化 | O(2^N) | 引入记忆化 |
完整反模式详情:参见 references/anti-patterns.md
优化模式库:参见 references/optimization-patterns.md
完整示例:参见 references/examples.md
复杂度公式:参见 references/complexity-formulas.md
| 语言 | 关键优化点 |
|---|---|
| C++ | reserve()、unordered_map、移动语义、std::span、基于范围的算法 |
| Java | 带容量参数的 StringBuilder、原始类型流(IntStream)、ArrayDeque |
| Python | 列表推导式、collections 模块、生成器、成员判断优先使用 set() |
若你发现自己产生如下想法,请立即停止:
以上任一情形出现,均意味着:立即暂停。严格遵循既定工作流。
| 借口 | 事实 |
|---|---|
| “问题很简单,无需分析” | 简单问题同样有其根本原因。务必先做计算与分析。 |
| “先试试这个修复方法” | 首次修复会确立后续模式。必须从一开始就做对。 |
| “测试通过,说明优化有效” | 测试通过 ≠ 复杂度得到改善。必须实测验证。 |
| “同时应用多个优化” | 无法定位真正起效的变更项。每次仅允许一项变更。 |
| “我稍后再做测量” | 测量是证明优化有效的唯一依据。必须立刻执行。 |
切勿对关键性能代码凭空猜测约束条件。应主动询问:
在宣称优化成功之前,必须完成以下验证:
各语言性能剖析命令:
C++:
g++ -O2 -pg solution.cpp -o solution ./solution input.txt gprof solution gmon.out > analysis.txt
Java:
java -Xprof Solution
Python:
python -m cProfile -s tottime solution.py
伸缩性测试(Scaling test):
for size in 100 1000 10000 100000; do
time ./solution input_${size}.txt
done
# 预期:O(N) 应呈线性增长;O(N log N) 应呈近似线性对数增长
# 警告:若输入规模翻倍导致耗时增至约四倍,则表明仍为 O(N²)
相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.6万人学习
最新文章