本仓库是熊英飞老师组为 2026 年北京大学科研轮转设计的实践项目之一,主要涉及和大模型相关的程序优化技术。
如果在完成项目的过程中遇到了任何问题,请随时通过微信或者邮件 (zhaoyuwei@stu.pku.edu.cn) 与负责的同学联系。另外,请大家善用大模型,可以解决很多问题。
程序优化在现代计算领域具有重要意义,它直接关系到软件的执行效率、资源利用率以及用户体验。在性能需求不断提高和硬件环境日益复杂的背景下,传统的优化手段往往面临规则设计繁琐、自动化程度不足等瓶颈。而大模型凭借强大的自然语言理解与生成能力,以及在模式识别和知识推理中的卓越表现,为解决这些问题提供了新的可能。通过将大模型应用于程序优化任务,我们可以探索更加智能化、自动化的优化手段,从而提升程序开发效率并实现更高效的代码性能。
- Part1:尝试使用 API 来调用大模型,了解 API 相关的设置。了解提示工程技术。
- Part2:了解如何构建代码优化知识库。从 GitHub 获取 commit 信息,使用 LLM 判断是否为代码优化,最终理解 SemOpt 知识库的构建流程和使用方式。
- Part3:使用大模型自动优化代码。实现并对比三种方法:Direct Prompt、RAG、Claude Code Skill。
- Part4:阅读相关论文,了解程序优化领域的前沿工作。
- Part5:尝试使用 SemOpt 的完整流程。
- Part6:进阶探索,改进现有方法或提出新的想法。
注意:Part4-6 的顺序不是固定的,可以交叉完成。Part5 和 Part6 为可选内容。
推荐时间分配 基础路线:
- Part1:1 周(基础工具)
- Part2:0.5 周(知识库理解)
- Part3:1.5-2 周(自动优化代码,至少完成 Direct Prompt + 一种进阶方法)
- Part4:1 周(阅读论文)
深度探索:
- Part1:0.5 周
- Part2:0.5 周
- Part3:1.5-2 周(实现全部三种方法并深入对比)
- Part4:1 周(精读多篇论文)
- Part5-6:1+ 周(可选,深度探索)
本部分目标: 掌握项目所需的基础工具,包括 Git、命令行、LLM API 调用和提示工程技术。
该部分的构成如下:
- 1.1:简单学习 Git 以及命令行的使用
- 1.2:尝试使用 API 来调用大模型,了解 API 相关的设置
- 1.3:了解提示工程技术(重点:RAG 和 Claude Code Skill)
- 学习命令行的基本使用方式
- 运行 python 脚本
- 在本地配置 python 环境,并尝试在命令行运行
python hello_world.py - 如果需要的话,可以尝试使用 pyenv 工具管理 python 版本。
- 在本地配置 python 环境,并尝试在命令行运行
- 学习 Git
- 参考 https://missing-semester-cn.github.io/2020/version-control/
- 了解如何进行简单的版本管理
- 了解 GitHub 的主要用法,例如可以从以下几个问题入手
- 配置环境,并在命令行使用
git clone来下载代码,例如可以下载本项目。尝试使用git pull来获取代码库的更新。 - 尝试在 GitHub 网页上查看 commit 信息。
- 尝试在 GitHub 上创建仓库,并使用
git push将本地的代码同步更新到 GitHub。- 注意:如果你需要在本项目的基础上进行修改,并希望将代码保存到 GitHub,请另外新开一个仓库来存储你自己的代码,而不要直接修改本项目对应的仓库。例如你可以使用 GitHub 上的 fork。
- 配置环境,并在命令行使用
我们组使用大模型门户来调用各类模型,包括 Claude、OpenAI、DeepSeek 等模型,请联系负责同学获取账号。每位同学的限额是每月100刀,组内统一报销费用,只能用于自己的科研轮转项目,不能转借或者倒卖。
另外注意保护好自己的 api key,防止泄露。如果要在 GitHub 上存放项目,注意不要将 api key 同步更新上去(config.py 已在 .gitignore 中,不会被提交)。如果发现 api key 有可能已经泄露,请立刻联系管理员重置秘钥。
配置步骤:
-
复制根目录下的
config_template.py文件并重命名为config.py -
编辑
config.py文件,填入以下变量:GITHUB_TOKEN:使用 GitHub api 时需要的配置,在 GitHub - Settings - Developer Settings - Personal access tokens - Tokens (classic) 中生成一个然后复制进来就行xmcp_base_url:调用大模型相关,在大模型门户上的"API 调用秘钥/BASE_URL"一栏获取,已设置好xmcp_api_key:调用大模型相关,在大模型门户上的"API 调用秘钥/API_KEY"一栏获取自己账号的 api key 并放到这里xmcp_model:调用大模型相关,在大模型门户上查看模型列表,选择想要调用的模型,然后将"模型名称"复制到这里,例如volc/deepseek-v3-250324
-
part1/test_api.py是一个简单的大模型调用示例,尝试使用python test_api.py来运行这个脚本
参考以下资料了解如何通过 api 调用大模型以及相关的参数设置(OpenAI 和 DeepSeek 用的同一个库,所以可以先阅读 DeepSeek 文档,了解基本设置):
主要的设置包括:
- message:https://api-docs.deepseek.com/zh-cn/
- role
- content
- temperature:https://api-docs.deepseek.com/zh-cn/quick_start/parameter_settings
- logprobs: https://cookbook.openai.com/examples/using_logprobs & https://api-docs.deepseek.com/zh-cn/api/create-chat-completion
- 对话补全:https://api-docs.deepseek.com/zh-cn/api/create-chat-completion
- JSON Output:https://api-docs.deepseek.com/zh-cn/guides/json_mode
- 上下文硬盘缓存:https://api-docs.deepseek.com/zh-cn/guides/kv_cache
- ...
尝试基于 test_api.py 来调用大模型并解决简单的问题,尝试调整输入的参数以及获取输出的各类信息。
参考以下资料了解提示工程技术:
- https://www.promptingguide.ai/zh
- OpenAI Prompt Engineering: https://platform.openai.com/docs/guides/prompt-engineering
- Anthropic Prompt Engineering: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview
基础技术包括:
- 零样本提示
- 少样本提示
- 链式思考(CoT)提示
相对复杂的技术包括(这两个技术都将在后续 Part3 中使用):
- 检索增强生成 (RAG)
- RAG(Retrieval-Augmented Generation)是一种结合检索和生成的技术,通过从知识库中检索相关信息并作为上下文提供给大模型,从而提高生成内容的准确性和相关性。
- https://www.promptingguide.ai/zh/techniques/rag
- https://www.zhihu.com/tardis/zm/art/675509396?source_id=1003
- https://arxiv.org/abs/2005.11401: 提出 RAG 技术的论文
- Claude Code Skill
- Claude Code Skill 是一种让 AI 助手能够使用预定义技能(Skills)来完成特定任务的技术。通过提供结构化的策略库或技能库,可以让 LLM 在面对特定问题时,先从策略库中选择合适的策略,再应用到具体任务中。这种方法结合了专家知识和 LLM 的推理能力,提供了更好的可解释性。
- Claude Code Skill 官方文档:https://code.claude.com/docs/en/skills
本部分目标:了解如何构建代码优化知识库。通过学习获取 commit 信息和判断代码优化这两个步骤,理解 SemOpt 知识库的构建流程,为后续的自动优化任务做准备。
该部分的构成如下:
- 2.1:从 GitHub 获取 commit 信息
- 2.2:使用大模型判断 commit 是否为代码优化
- 2.3:了解 SemOpt 知识库的结构和使用
为什么要了解知识库构建? 在 Part3 中,我们将使用大模型自动优化代码,其中 RAG 和 Claude Code Skill 两种方法都需要使用历史优化案例。理解知识库的构建过程和结构,可以帮助你更好地使用这些方法。
该部分将使用来自 100 个 C/C++ 代码库的代码优化 commits 作为示例。这些 commits 都是只修改了一个 C/C++ 文件中某个函数的代码优化提交。
数据说明:
data/repo_list.json:包含本项目使用的 100 个 C/C++ 开源代码库的详细信息,包括代码库名称、URL、简介、commit 数量、优化 commit 统计等元数据。data/benchmark.json:从这 100 个代码库中筛选出的代码优化 commits 的测试集。data/all_is_opt_final.json:所有代码库的优化 commits 汇总数据。data/0_76.json:聚类结果文件。
编写脚本,在给定代码库以及 commit hash 后,自动获取该 commit 对应的信息。主要有以下两种思路:
方法 1(推荐):如果 commit 集中来自于一个或多个代码库,可以考虑将整个代码库下载到本地,并且直接从 git 信息中获取需要的部分。
方法 2:如果 commit 分散在许多不同的代码库,可以考虑直接调用 GitHub API,获取对应的 commit 信息。GitHub API 有调用频率的限制,主要有以下几种解决方法:
- 多注册几个账号获得更多的 key
- 纯等待,例如每调用一次 API 之后
sleep(n) - 改用方法 1
练习:编写脚本,从 GitHub 获取 commit 信息。可以使用 data/benchmark.json 中的任意一个 commit 来尝试实现上述功能。尝试获取该 commit 的信息并用合适的文件类型和格式来保存这些信息,可以提取的信息包括:
- Commit message
- 修改的文件列表
- 每个文件的具体修改内容(diff)
- 修改前后的完整文件内容
编写 Python 脚本,判断一个 commit 中代码修改的主要目的是否为代码优化(只包括提高代码运行效率 / 减少运行所需资源,不包括改善代码可读性和可维护性等)
具体步骤:
-
从代码库的 git 信息中获取 commit 信息(使用 2.1 中的方法)
-
给出 commit 的具体信息(例如 commit message,具体的代码修改信息),让大模型给出答案
- 如何让大模型只回答
true/false/unknown(在大模型不确定的时候就回答unknown) - 如何提高大模型的回答准确率
- 是否有一些类型的任务大模型认为不是代码优化,但在人类判断的结果上属于代码优化(比如优化内存访问的效率),尝试通过修改 prompt 来改善这一问题
- 如何让大模型只回答
总结: 通过 2.1 和 2.2,你已经了解了构建代码优化知识库的前两个步骤:获取 commit 信息和判断是否为代码优化。这正是 SemOpt 论文中知识库构建的核心流程。在 2.3 中,我们将进一步了解完整的 SemOpt 知识库。
在这一小节中,我们将了解本项目提供的 SemOpt 知识库的结构和内容。SemOpt 是一个结合大语言模型的自动代码优化工具,目前可用于优化 C/C++ 代码中的函数性能。这个知识库是通过 2.1 和 2.2 中的方法,从 100 个 C/C++ 开源项目中构建而成的。
SemOpt 知识库的构建流程如下:
- 收集代码库:选择 100 个活跃的 C/C++ 开源项目(如 Redis、RocksDB、FFmpeg 等)
- 获取 commits:从每个项目的 git 历史中获取所有 commits(使用 2.1 的方法)
- 筛选 commits:只保留满足以下条件的 commits
- 只修改了一个 C/C++ 文件中的代码
- 只修改了该文件中的一个函数
- 没有修改任何不属于该函数的代码
- 判断优化类型:使用 LLM 判断每个 commit 是否为代码优化(使用 2.2 的方法)
- 提取修改信息:对于筛选后的代码优化 commits,提取修改前后的代码
- 聚类分析:
- 首先使用 LLM 为每个 commit 生成文字描述,总结其具体使用的优化策略
- 然后对这些文字描述进行 embedding(向量化)
- 最后使用聚类算法(如 DBSCAN),将采用相似优化策略的 commits 归为一类
- 构建知识库:保存所有信息,形成结构化的知识库
最终得到 1968 个代码优化 commits,聚类后形成 151 个策略簇(覆盖约 25% 的 commits)。
知识库位于 knowledge_base/ 目录下,结构如下:
knowledge_base/
├── {repo_name}/ # 每个代码库一个文件夹
│ ├── is_opt_final.json # 该代码库的所有代码优化 commits 元数据
│ └── modified_file/
│ └── {commit_hash}/ # 每个 commit 一个文件夹
│ ├── before.c # 优化前的完整文件
│ ├── after.c # 优化后的完整文件
│ ├── before_func.c # 优化前的函数(如果只修改了一个函数)
│ ├── after_func.c # 优化后的函数
│ └── diff.txt # 代码差异
所有代码库的优化 commits 汇总数据位于 data/all_is_opt_final.json,该文件包含了所有代码库的优化 commits 元数据(2529 个 commits)。并不是所有 commit 后续都用于聚类,因为部分 commit 的细节处理有一些问题,所以没能获取到完整的信息,后续就没有用于聚类,但这些细节不是很重要。
聚类结果位于 data/0_76.json,其中 0_76 表示使用的相似度阈值为 0.76。
聚类统计:
- 总 commits 数:1968 个
- 聚类簇数:151 个
- 聚类覆盖率:约 24.7%(487 个 commits 被分到某个簇中)
- 噪声点:约 75.3%(1481 个 commits,可能包含更复杂或独特的策略)
在后续的 Part3 中,我们将使用这个知识库来辅助大模型进行代码优化。主要有两种使用方式:
-
RAG(检索增强生成):
- 给定待优化的代码,从知识库中检索相似的优化案例
- 将检索到的案例作为 few-shot 示例提供给 LLM
- LLM 参考这些示例进行优化
-
Claude Code Skill(策略库):
- 从聚类结果中提取优化策略的描述
- 构建策略库(每个策略包含描述和代表性示例)
- LLM 先从策略库中选择合适的策略,再应用到代码上
(可选)探索知识库 你可以编写简单的脚本来探索知识库,例如:
- 列出所有代码库及其 commits 数量
- 查看某个代码库的所有优化 commits
- 查看某个策略簇的代表性案例
- 按优化类型筛选 commits
这将帮助你更好地理解知识库的内容,为 Part3 的任务做准备。
本部分目标: 实现并对比三种自动代码优化方法:Direct Prompt(baseline)、RAG、Claude Code Skill。理解不同方法的优劣,学习如何评估优化结果。
现在我们只考虑那些只修改了一个函数并且主要实现代码优化的 commit,然后尝试使用大模型来自动优化代码(即尝试复现 commit 中的修改)。在开始自动优化之前,我们需要先理解 benchmark 中的优化任务,这样才能更好地评估自动优化工具的效果。我们将实现以下流程(3.1、3.2、3.3必做,3.4和3.5二选一即可):
- 3.1:理解 commits(必做)- 介绍 benchmark,手动分析优化任务
- 3.2:Direct Prompt 方法(必做)- 统一的 prompt,作为 baseline
- 3.3:编写评估脚本(必做)- 评估优化结果的正确性和性能提升
- 3.4:RAG 方法(二选一)- 检索相似案例作为参考
- 3.5:Claude Code Skill 方法(二选一)- 使用策略库引导优化
- 3.6:总结与分析(必做)- 对比不同方法的效果
在开始实现自动优化工具之前,我们需要先了解我们的测试数据集(benchmark),理解里面的 commits 都完成了什么样的优化任务。这样可以帮助我们:
- 了解后续自动优化工具需要完成什么样的任务
- 为评估自动优化结果建立基准认知
- 识别出哪些优化任务适合让大模型自动完成
测试数据集位于 data/benchmark.json,包含来自 100 个 C/C++ 开源代码库的 151 个代码优化 commits。每个 commit 都满足以下条件:
- 只修改了一个 C/C++ 文件中的一个函数
- 主要目的是提升代码运行效率或减少资源消耗(代码优化)
- 已经过筛选和人工验证
这个 benchmark 将作为后续自动优化工具的测试数据集,你的目标是让大模型自动复现这些 commits 中的优化修改。
建议:完整的 benchmark 包含 151 个优化任务,规模较大。在初步探索阶段,建议先从小规模开始,例如可以手动挑选或随机抽取 10 个左右的优化任务进行实验。待初步方法实现完成、流程跑通后,再逐步扩大测试规模到更多的 benchmark 任务,以便更全面地评估不同方法的效果。
为了方便使用,我们将 benchmark 中所有 commits 对应的代码文件提取到了 benchmark/ 目录下,结构如下:
benchmark/
├── {repo_name}/ # 每个代码库一个文件夹
│ └── modified_file/
│ └── {commit_hash}/ # 每个 commit 一个文件夹
│ ├── before.c # 优化前的完整文件
│ ├── after.c # 优化后的完整文件
│ ├── before_func.c # 优化前的函数
│ ├── after_func.c # 优化后的函数
│ └── diff.txt # 代码差异
注意:文件扩展名可能因代码库不同而有所差异(如 .c、.cpp、.h、.cc 等),但文件名前缀保持一致。
虽然这些 commit 都是只修改了一个函数的小规模修改,但部分修改内容依然可能非常复杂,对于一个并不了解该代码库的程序员来说,也很难快速读懂每一处修改的目的。建议你从 benchmark 中选择 5-10 个 commits,手动分析它们的优化策略。你可以结合 commit message 和代码修改内容进行分析,也可以让大模型辅助分析。
在分析每个 commit 时,可以关注以下几个方面:
-
优化策略的可理解性
- 人工分析后是否能理解代码修改确实能够提升性能
- 如果人类也无法理解这样的改动是否有效,可以暂时先不考虑这样的 commit
-
修改的一致性
- 是否将几个独立的修改内容放在了一个 commit 中
- 还是所有代码修改都为一个共同的目的服务
- 如果是前者,也可以暂时不考虑
-
对项目上下文的依赖程度
- 依赖项目特定信息:例如项目中的特定 API 接口,或者需要了解项目运行时的瓶颈
- 几乎不依赖项目特定信息:例如调整 if 条件中的子条件顺序,这种相对通用的修改
-
修改的复杂度
- 是否涉及几十甚至上百行代码
- 是否需要在一个几百行的函数中修改很多地方
- 过于复杂的修改可能导致大模型难以给出正确的优化结果
提示:可以通过 data/benchmark.json 中的 github_commit_url 字段访问每个 commit 的详细信息,或者使用 benchmark/{repository_name}/modified_file/{commit_hash}/ 目录下的文件查看修改前后的代码。
在完成手动分析后,建议记录以下内容:
- 这些 commits 主要使用了哪些优化策略(例如:缓存计算结果、调整条件顺序、使用更高效的数据结构等)
- 哪些类型的优化看起来更容易被自动工具复现
- 哪些优化可能需要深入的项目知识或复杂的推理
这些分析结果将帮助你在后续的自动优化过程中,更好地评估不同方法的效果,并理解什么样的 commit 适合让大模型来自动复现优化。
方法描述: 在所有任务上使用统一的 prompt,作为 baseline 方法。我们不会在 prompt 中告诉大模型当前代码可以在什么方面进行优化,而是完全让大模型自行决定每一步的结果。这是一种完全自动化的方法。
可能的技术方案:
- 单轮对话:直接在 prompt 中给出需要被优化的代码,并要求大模型分析代码中可能存在的代码优化问题并给出优化结果。
- 使用 CoT:引导大模型先阅读并理解给出的代码,然后分析有什么代码优化的可能(大模型可能会给出多个方向,也可以在 prompt 中加入限制,要求大模型给出不超过三个的优化方向),然后依次要求大模型给出每种方向上的优化结果。
需要关注的问题:
- 分析大模型给出的优化方式有哪些类型,是否有一些是我们不想要的(例如提升代码可读性、可维护性等),调整 prompt 来规避这些可能。
- 判断大模型给出的优化是否是正确的方向,以及优化的结果是否保持语义不变并且有真正的性能提升。
提示:从少量 commits(5-10 个)开始测试,记录结果用于后续对比。
无论使用哪种方法优化代码,都需要评估优化结果的正确性和性能提升。编写评估脚本,主要包含以下几个方面:
最严格的评估标准:生成的代码是否与原始优化后的代码完全一致。需要对代码进行正则化处理,包括去除注释、忽略空格、换行、制表符(tab)、空行等格式差异。正则化后的代码如果完全一致,就认为优化成功复现了原始 commit。这个评估可以通过编写脚本自动完成。
除了完全匹配,还需要评估优化结果是否保持了语义正确性并实现了性能提升。主要包含以下几个方面:
- 语法正确性(Syntax Correctness):代码是否可以编译通过
- 语义等价性(Semantic Equivalence):优化后的代码语义是否保持不变
- 性能提升(Performance Improvement):是否真正实现了性能提升
评估方法:
方法 1:实际测试(最准确但最复杂)
- 将优化后的代码替换到完整代码库中,尝试编译整个项目
- 运行代码库的 unit test 验证语义等价性
- 运行 performance test 或编写 micro-benchmark 测试性能
- 局限性:需要配置复杂的编译环境和测试环境,实际操作困难
方法 2:人工判断(实用且可靠)
- 阅读优化前后的代码,判断语法是否正确
- 分析代码逻辑,判断语义是否等价
- 根据修改内容推断是否应该有性能提升
方法 3:LLM 辅助判断(快速但需谨慎)
- 设计合适的 prompt,让 LLM 分析代码的语法、语义和性能
- 可以作为辅助手段,但不完全可靠,建议结合人工判断
建议:对于 benchmark 中的 commits,如果配置测试环境困难,使用人工判断或 LLM 辅助判断是可以接受的评估方式。
RAG(Retrieval-Augmented Generation)是一种结合检索和生成的方法。给定待优化的代码,先从知识库中检索相似的优化案例,然后将这些案例作为 few-shot 示例提供给 LLM,引导 LLM 进行优化。
RAG 流程:
- 检索相似案例:从 SemOpt 知识库中检索与当前代码相似的优化案例
- 构建 prompt:将检索到的案例(优化前后的代码对比)加入到 prompt 中
- 生成优化结果:LLM 参考这些示例进行优化
- 评估结果:使用 3.3 中的评估方法
基于代码相似度的检索方法,这是 RAG 方法中最核心的步骤,通过计算代码之间的语义相似度来找到最相关的优化案例。具体流程如下:
-
预处理知识库
- 遍历 SemOpt 知识库中的所有优化案例
- 对每个案例的优化前代码进行 embedding(向量化),得到代码的语义向量表示
- 可以使用 OpenAI 的 embedding 模型(如
text-embedding-3-small)或专门的代码 embedding 模型(如 CodeBERT) - 将所有案例的 embedding 向量存储起来,以便后续快速检索
-
获取目标代码的 embedding
- 对待优化的目标代码进行同样的 embedding 处理
- 确保使用与知识库相同的 embedding 模型和参数
-
计算相似度
- 计算目标代码与知识库中所有案例的相似度
-
选择 top-k 案例
- 根据相似度分数排序,选择 top-k 个最相似的案例
- 可以设置相似度阈值,过滤掉相似度过低的案例
- 返回这些案例的完整信息(优化前代码、优化后代码、diff、元数据等)
在构建 RAG 的 prompt 时,需要将检索到的案例放入 prompt 中作为 few-shot 示例。请阅读论文:https://ieeexplore.ieee.org/abstract/document/10298329,理解 few-shot 示例选择和排序的影响,然后回答以下三个问题:
- 放哪些案例?
- 放几个案例?
- 按照什么顺序放案例?
根据你从论文中得到的答案,设计合适的 prompt 模板来构建 RAG 方法。
Prompt 模板示例(最好用英文的,这里是随便的一个例子):
你是一个代码优化专家。以下是一些历史的代码优化案例,请参考这些案例来优化给定的代码。
案例 1 (来源: redis, commit: abc123):
优化前:
[before code]
优化后:
[after code]
优化说明: [简短描述优化策略]
(其他案例...)
现在,请优化以下代码,保持语义不变的同时提升运行效率:
[target code]
要求:
1. 只输出优化后的完整代码
2. 确保优化后的代码语义与原代码完全一致
3. 优化应该能够实际提升代码的运行效率
- 对比 RAG 方法中不同知识库过滤策略的效果:
- 策略1(排除单个commit):在知识库中仅排除当前 benchmark 对应的那个 commit,允许检索来自同一代码库的其他 commit
- 策略2(排除整个代码库):在知识库中排除当前 benchmark 对应的 commit 所在代码库的所有 commit,强制跨代码库检索
- 分析目标:评估能否获取来自同代码库的代码修改例子对 RAG 方法正确性的影响。这个对比实验可以帮助理解:(1) 同代码库的历史优化经验是否对当前优化任务更有帮助;(2) 跨代码库的泛化能力如何;(3) 是否存在因同代码库示例导致的过拟合或信息泄露问题。
Claude Code Skill 是一种基于策略库的方法。通过构建层次化的策略知识库,让 LLM 先从策略目录中选择合适的策略,再参考该策略的详细信息进行代码优化。这种方法结合了专家知识和 LLM 的推理能力,提供了更好的可解释性,并且通过两阶段的设计降低了单次调用的上下文长度。
基于 knowledge_base/ 和 data/0_76.json 中的聚类结果,构建层次化的策略知识库,包含以下两类文件:
文件 1:策略目录
- 包含所有优化策略的简要列表
- 每个策略包含:
- 策略 ID
- 策略简要描述(1-2句话)
- 可以使用 LLM 从聚类簇中自动生成策略描述
- 这个文件用于第一阶段的策略选择,应当简洁明了
文件 2:策略详细文档
- 每个策略对应一个独立的详细文档
- 包含的信息(不限于列出的这些):
- 策略的详细描述(使用场景、优化原理等)
- 若干个代表性的 commit 案例(包含优化前后的代码对比)
- 应用该策略的前置条件(例如:代码需要满足什么特征才适合使用此策略)
- 可以使用 LLM 分析聚类簇中的案例,自动生成上述信息
阶段 1:策略选择
- 输入:
- 策略目录文件
- 待优化的函数代码
- 任务:让 LLM 分析代码,从策略目录中选择最适合的 0/1 个策略
- 输出:选中的策略 ID
阶段 2:代码优化
- 输入:
- 选中策略的详细文档
- 待优化的函数代码
- 任务:让 LLM 参考策略的详细信息和示例,生成优化后的代码(如果阶段1没有选中任何策略,那就用固定的 prompt 要求 LLM 直接给出优化结果)
- 输出:优化后的完整代码
-
策略库构建脚本
- 读取
data/0_76.json获取聚类结果 - 对每个聚类簇,使用 LLM 生成策略描述和前置条件
- 从
knowledge_base/中提取每个簇的代表性案例 - 生成策略目录文件和各个策略的详细文档
- 读取
-
策略选择 prompt 设计
- 清晰展示所有可选策略的 ID 和描述
- 引导 LLM 分析代码特征与策略匹配度
- 要求 LLM 输出结构化的策略 ID
-
代码优化 prompt 设计
- 提供选中策略的完整信息和案例
- 强调保持语义等价性
- 要求输出完整的优化后代码
-
评估结果:使用 3.3 中的评估方法
完成 3.1-3.5 后,进行总结与分析:
- 哪种方法在你的测试集上表现最好?为什么?
- 不同方法在什么类型的优化任务上表现更好?
- 如何结合多种方法的优势?
- 还有哪些可能的改进方向?
(可选)进阶方向:
- 尝试组合不同方法(例如:先用 RAG 检索,再用 Claude Code Skill 选择策略)
- 分析失败案例,总结大模型的局限性
- 在更大的测试集上验证结果
本部分目标: 通过阅读论文,了解程序优化领域的前沿工作,理解理论和实践的关系。
阅读以下论文,可以先粗略过一遍所有论文,然后在优化小规模代码 / 大规模代码中选择一个感兴趣的方向进行精读。
- SemOpt: A Semantic Optimization Framework for Large Language Models
- 论文链接:https://arxiv.org/abs/2510.16384
- 说明:这是本项目知识库的来源论文。阅读这篇论文可以帮助你理解:
- 知识库是如何构建的
- 聚类方法的设计思路
- 完整的 SemOpt 方法(比 Part3 中的方法更复杂)
- 实验设计和评估方法
-
同一个作者的前后两篇连续的工作
- DeepDev-PERF:https://dl.acm.org/doi/abs/10.1145/3540250.3549096
- RAPGen:https://arxiv.org/abs/2306.17077
-
Performance Bug 相关
- TANDEM:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9110902
- A Large-Scale Empirical Study of Real-Life Performance Issues in Open Source Projects:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9757842
PIE 和 SBLLM 是比较主要的论文。
- PIE:https://arxiv.org/abs/2302.07867
- Learning to Improve Code Efficiency:https://arxiv.org/abs/2208.05297
- Supersonic:https://ieeexplore.ieee.org/abstract/document/10606318/
- SBLLM:https://arxiv.org/abs/2408.12159
参考 SemOpt 论文,尝试运行完整的优化流程。(具体需要用到的代码和策略库没有放进来,可以单独联系)
本部分目标:发现现有方法的局限性,提出改进方案并验证。这是一个开放性的探索部分,鼓励提出自己的想法。
在使用 SemOpt 策略库的过程中,你可能会发现策略库存在一些局限性:
观察到的问题:
- 策略覆盖率低:只有约 25% 的 commits 被聚类,75% 的 commits 是噪声点
- 策略过于简单:聚类得到的策略大多是简单的优化模式,缺少复杂的优化策略
- 策略不够细粒度:一些策略簇包含的案例差异较大,可能需要更细的分类
可能的原因:
- 聚类阈值设置:当前使用 0.76 的相似度阈值可能过高,导致很多复杂案例被归为噪声
- 聚类算法选择:当前使用的聚类算法可能不适合代码优化场景
- 筛选策略问题:可能在筛选过程中过滤掉了一些有价值的复杂优化案例
类似的,SemOpt 也存在其他的局限性,例如目前只能优化单个函数,无法实现跨函数甚至跨文件的优化等。