文章总结: IRify优化2.0实现四项核心重构:SSA指令搜索从字符串匹配转为常量池ID路径优先,秒级热点降至毫秒级;SyntaxFlow条件判断重构消除大量值场景循环瓶颈;ANTLR缓存清理参数经实验确定100为速度与内存稳态甜点;Java与PHP前端通过SLL-first统一解析及PHPToken合并使混合HTML基准耗时下降约55%。后续聚焦内存压缩与懒构建。 综合评分: 86 文章分类: 安全工具,代码审计
深度拆解 IRify 性能优化2.0:从能跑到稳快省的全路径重构
原创
YAK YAK
Yak Project
2026年3月27日 18:30 北京
#
先说几个最直观的结果。
- 在真实目标
spring-cloud-netflix上,这一轮 CodeScan 调优过程中的观测值,从10.08s降到了5.59s。 - 在 SSA 指令搜索这条线上,
sfvm.nativecall:getFormalParams:java-servlet-param这一类核心热点,已经从早期的6.065s量级压到了“几十毫秒”量级。 - 在 PHP mixed HTML 这个最典型、也最难看的前端热点上,
BenchmarkFrontendPfsenseSystemInformationFixture从15.36s/op降到了6.95s/op,时间下降约54.74%;本地当前主线补跑时,结果也稳定在7.82s/op左右。 - 在 Java 大型反编译目标的 AST-only 实验里,ANTLR 缓存清理参数调优前后,可以从
78.46s / 19.34GB这类结果,压到53.01s / 5.63GB这一档;如果追求更激进的速度甜品点,也已经能跑到51s左右。 - 在 Java 反编译大项目目标上,前端 AST 错误和 panic 已经被清到 0,系统瓶颈开始从“前端根本过不去”后移到“落库和持久化阶段怎么继续压”。
这几组数据放在一起,其实已经能说明很多问题:
第一,当前这一轮优化,已经不是“体感更快一点”的级别,而是真正把一批秒级、十秒级、甚至十几 GB 内存级别的问题打下来了。
第二,这一轮优化的重点,不只是提速,还包括把热点找准、把路径理顺、把默认参数选稳。
第三,现在已经落地的是第二轮结果,接下来会继续进入第三轮、第四轮。
这轮已经落地的内容,可以先概括成四件事:
1、SSA 编译和搜索路径更统一了,相关命令和文档也同步整理到了 ssa.to/docs。
2、SSA 指令搜索开始从字符串匹配路径,推进到“常量池 + ID 路径”的结构优化。
3、SyntaxFlow / SFVM 的判断语句运行逻辑被重构了一轮,过去在大量值场景下容易拖很久的判断路径,被真正收住了。
4、ANTLR / front-end 不只是继续修语法边界,还开始通过参数 sweep、统一目标实验和 TokenSource 优化,系统性地压时间和内存。
与此同时,这并不是终点。
当前仓库里的 worktree 已经能明显看出后续方向还在继续推进,对应的其实就是下一阶段要继续啃的几块硬骨头:
- 编译期内存和数据存储继续压缩
- 时序和诊断能力继续补强
- lazy build 路径继续推进
- 数据流分析能力继续细化
所以,如果用一句话概括这篇文章想讲的内容,那就是:
这一轮 IRify 性能优化,已经把“能不能跑”推进到了“怎么跑得更快、更稳、更省”,而后面的第三轮、第四轮,也已经开始排上日程。
下面就按几个最关键的位置,分别讲清楚这轮到底优化了什么、为什么要这么做、以及它现在带来了什么结果。
这一节对应的核心合并 PR 主要是:#4019、#4040、#4066、#4092。
之前的情况
这一轮之前,IRify 在 SSA 指令搜索上的核心能力已经是可用的,问题主要集中在“越大项目越容易把搜索路径拖慢”。
真正慢下来的位置,主要不在某一条规则本身,而在搜索链路背后的数据形态:
- 指令、变量、成员、对象 key 这些名字,在持久化时会被抹平成数据库里的字符串字段
irindex这类索引表里,name字段存在大量重复- 一旦大项目里“很多值都叫同一个名字”或者“重名值特别多”,搜索就会在大量重复名字上反复做工作
也就是说,旧路径的问题不是“有没有搜索能力”,而是搜索时还带着太多字符串级别的重复劳动。
问题
这轮最开始最容易误判的地方,就是把热点简单理解成“正则匹配慢”。
实际上,真正的问题在更底层:
1、数据库里保留下来的是“名字到值”的映射,但重名很多。
2、一旦用字符串去搜,数据库会不断在重复名字上做重复匹配。
3、SQLite 的回调式正则在这种高重复场景下会进一步放大成本。
所以根因不是一句“正则慢”能解释的。
更准确地说,是:
同名值太多,字符串搜索路径又太重,导致数据库不断在重复名字上做重复工作。
这也是为什么这一轮最终会走到“常量池优化”。
这里说的常量池,实际落点就是 namepool 这条路径:先把名字集中管理,再尽量把搜索从字符串匹配推进到 id 路径。
方案
这条线真正的突破,不是直接大改,而是先做实验。
先做的几件事非常关键:
- 在同一个真实目标
spring-cloud-netflix上,反复跑 scan-only 基线 - 把热点拆到具体执行点
- 尝试把搜索数据 load 到内存里,验证是否能绕开 SQLite 的回调式正则
- 进一步分析
irindex里name的重复度
实验做下来以后,方向就清楚了:
1、先从内存里把重复名字去重。
2、再对去重后的名字集合做匹配。
3、匹配完成后,再反查对应值。
4、再进一步,把字符串匹配路径推进到 id 路径,也就是常量池 / 名称池。
最终落到代码里的几个关键位置是:
common/yak/ssa/ssadb/name_cache.gocommon/yak/ssa/database_search.gocommon/yak/ssaapi/sf_search.gocommon/yak/ssaapi/sf_native_call.go
具体改动包括:
- memory mode 补上纯内存常量池
- 搜索从
pattern -> string改成pattern -> NameCache IDs -> value IDs SearchWithValue加上 lazy / DB fast pathNativeCall_GetFormalParams改成尽量不 materialize 完整函数对象
现在的情况和重构结果
现在这条链路最重要的变化,不是“加了个缓存”,而是搜索模型已经换掉了:
- 不再优先做大范围字符串匹配
- 开始优先走常量池 / namepool
- 先去重,再匹配,再按
id反查 - memory mode 和 DB mode 的搜索模型开始变得更接近
这也是为什么这一节应该叫“常量池优化”,而不是简单叫 namepool。
因为它背后解决的是一个更大的问题:
让搜索从“字符串不断重复扫”变成“名字集中管理、ID 路径优先”。
运行效率对比
这一节已经有几组很能说明问题的数据。
在 spring-cloud-netflix 的 scan-only 基线里,早期的核心热点包括:
| | |
| — | — |
| 热点 | 早期耗时 |
| sfvm.nativecall:getFormalParams:java-servlet-param | ~6.065s |
| sf.SearchWithValue:search-glob:*alibaba*fastjson | ~3.416s |
| sf.SearchWithValue:search-regexp:org.apache.logging.log4j | ~3.324s |
继续优化以后,这条线最亮眼的结果之一是:
sfvm.nativecall:getFormalParams:java-servlet-param
从秒级,压到了“几十毫秒”量级。
这基本就是两位数量级的下降。
同时,从整体观测值看,在同一个真实目标的调优过程中:
| | | |
| — | — | — |
| 观测项 | 调优前 | 调优后 |
| spring-cloud-netflix 观测值 | 10.08s | 5.59s |
这组整体数据不能简单说成“全靠常量池快了这么多”,因为中间还叠加了:
- scan-only 路径的使用
- 空规则噪音清理
- 其他热点修复
但它已经足够说明,SSA 指令搜索这条线的结构优化,已经开始实打实地把大项目扫描往下压了。
这一节对应的核心合并 PR 主要是:#4108、#4143、#4140。
之前的情况
SyntaxFlow 的过滤语法本身一直就很强,像这些写法大家都很熟:
a?{.b}a?{.*<len>==2}a?(*<len>==3)
从语法上看,它们都很好理解:
a?{.b}:判断每个a是否存在.ba?{.*<len>==2}:把a的成员展开后,判断这个a的成员数量是不是 2a?(*<len>==3):先展开,再在条件里对展开后的结果做判断
通过这些条件对?之前的a进行过滤。
在 ssa.to 的 SyntaxFlow 文档里,?{...} 一直都是按“每个输入值在自己的上下文里求值”来解释的。
但在运行时实现层面,这件事过去并没有被完全收得这么干净。
问题
这轮之前,真正的问题不是“语法表达不了”,而是运行逻辑上有几层历史包袱:
-
Values和旧的列表语义混在一起 -
条件判断、值分组、锚点回投之间边界不够清楚
-
condition 判断路径使用的是循环式处理思路
-
因为值本身存在前一个来自哪里的问题,判断以后需要映射回去,之前的初步实现方法是每个值进行循环判断。
这在简单规则里不一定明显,但一旦遇到:
- 输入值很多
- 条件嵌套很多
- 中间又做了
*展开、<len>、<slice>这类操作
就会出现一个很难受的现象:
规则不是不能跑,而是 condition 判断会沿着旧路径对值一个个循环判断,值越多,时间越长,几乎和值数量线性相关,所以一旦进入大量值场景就会非常慢。
所以这里的问题,不是“判断逻辑不正确”,而是:
判断逻辑在大量值场景下,执行路径不够稳定。
方案
这轮重构做的,是把这条判断路径整条收掉重来。
关键变化主要落在:
common/syntaxflow/sfvm/frame.gocommon/syntaxflow/sfvm/condition_exec.gocommon/syntaxflow/sfvm/native_call.gocommon/syntaxflow/sfvm/values.gocommon/syntaxflow/docs/sfvm-values-condition.md
核心思路有四个:
- 用
Values明确统一运行时值容器。 - 把条件判断统一收回
anchor-scope。 - 把
NativeCall的 grouped 行为也交回 SFVM 自己处理。 - 把旧的
ValueList和旧循环路径换掉。
在语义上,这轮重构之后,?{...} 的执行逻辑终于和 SyntaxFlow 文档里说的那一套真正对齐了:
a?{.b}不再走“把所有值拉出来逐个循环判断”的旧路径,而是一起执行对每个输入a单独判断它自己有没有.ba?{.*<len>==2}也不是把所有结果混在一起算,而是先标记前序,然后一起执行判断,再把判断结果映射回每个原始输入a
同样地:
a?{.*<len>==2}
也不再是把所有值全拍平后算一个总 len,而是:
- 先展开
- 再按原始输入
a回投 - 最后决定哪个
a应该保留
这也是为什么这轮方案的核心,不只是“换几个函数”,而是把:
ValuesConditionAnchorNativeCall
这一整组关系重新理顺。
现在的情况和重构结果
现在 SyntaxFlow 判断语句这条线,最重要的变化是:
- 判断语义和文档描述终于更一致了
- 条件判断路径更统一了
- 过去在大量值场景下容易拖很久的旧循环路径,被真正收住了
这件事在当前仓库测试里甚至有一个很直白的信号:
filter condition without iter loop
这个测试名本身就已经把问题说透了。
它不是在证明“能跑”,而是在证明:
这条条件过滤路径,现在已经不是靠旧的 iter-loop 逻辑在绕了。
运行效率对比
它的收益是“把长尾和坏路径收掉”。
- 之前:大量值进入条件判断后,容易一直循环判断,时间非常长
- 现在:这类判断路径和普通检索一样所有值一起执行,已经能稳定完成并且不需要任何循环操作。
也就是说,这一轮的收益主要体现在:
- 把不可接受的长尾收掉
- 把规则判断从“复杂时容易拖垮”变成“复杂时也能稳定执行”
这也是为什么这一节更像“运行逻辑重构”,而不是“一个单点提速 PR”。
这一节对应的核心合并 PR 主要是:#4139。
之前的情况
ANTLR 这条线的一个老问题是内存和时间,在之前的优化中我们先后完成了两个处理:
- 最开始我们发现内存不会被清理,然后清理出来不使用全局缓存而项目内缓存,以得到更稳定的缓存控制清理。
- 项目并发使用项目单一缓存将会带来锁的问题,导致并发执行非常慢,我们拆分出工作者协程并发,每个维护自己的缓存。
然后目前运行发现这带来了新的问题:runtime cache 会随着大项目不断膨胀,导致GC运行占用大量的cpu时间。
最关键的两个东西是:
- DFA
- PredictionContextCache
如果完全不管它们,在大目标上会越来越占内存;
但如果清得太勤,缓存来不及复用,解析的时间占用大部分导致整个的编译效率仍然会低。
所以这不是一个“开或关”的问题,而是一个需要实验判断的问题,我们需要在清理问题上找到一个指标并且寻找一个“甜点值”的配置作为默认。
问题
这条线真正要解决的是:
到底应该在什么时候清缓存,才能既不把内存推得太高,也不把性能打烂?
这件事必须同时看两组指标:
- 时间
- 峰值内存
因为只看其中一个,很容易选出一个看起来很好、但整体很差的策略。
方案
这轮的方案,不是拍脑袋改默认值,而是把缓存清理参数放出来,然后围绕统一目标持续做实验,比较不同参数下的时间和内存,再从结果里找一个真正合适的“甜品点”。
关键位置在:
common/yak/ssaapi/ssa_compile_utils.gocommon/yak/java/tests/ast_parse_metrics_local_test.go
最核心的环境变量是:
YAK_ANTLR_CACHE_RESET_FILES
它的含义很直接:
每个 worker 解析多少个文件以后,reset 一次 runtime cache。
接下来做的事情,就是围绕统一目标持续跑实验,比较不同 reset 周期下的时间和内存,去找那个真正合适的“甜品点”。
现在的情况和重构结果
这轮之后,ANTLR cache reset 已经不是一个模糊经验,而是一个有实验数据支撑的机制。
而且当前主线代码里,默认值已经落下来了:
YAK_ANTLR_CACHE_RESET_FILES=100
这个默认值不是拍脑袋写进去的,而是比较了一轮又一轮结果后,选出的更稳妥默认点。
运行效率对比
先看极端情况。
| | | | |
| — | — | — | — |
| 策略 | 时间 | 峰值内存 | 结论 |
| 不 reset | 78.46s | 19.34GB | 内存大,GC 压力也大 |
| 每次 parse 后都 reset | 88.54s | 2.20GB | 内存很低,但明显变慢 |
再看按“文件数”做 reset 的实验。
| | | |
| — | — | — |
| YAK_ANTLR_CACHE_RESET_FILES | 时间 | 峰值内存 |
| 100 | 53.01s | 5.63GB |
| 125 | 51.02s | 6.41GB |
| 145 | 50.17s | 7.09GB |
| 150 | 51.95s | 7.01GB |
| 250 | 50.67s | 9.67GB |
这张表很能说明问题:
145/150这一带,是速度上的“甜品点”100这一带,更偏向“速度和内存都稳”
所以这一轮最后落下来的结论不是:
- 某一个值绝对最优
而是:
- 存在一段明确的甜品区间
- 默认值应该选一个更稳、更容易接受的点
因此主线代码最终选择了:
- 默认
100
这个值没有追求单次最快,但它把时间和内存都压在了一个比较稳的区间里。
这一节对应的核心合并 PR 主要是:#4165,Java 相关 fixup 可对应 #4164,而通用 SLL-first 路径则和 #4139 连在一起。
之前的情况
这一节其实可以分成两条线:
- Java:主要问题是各种真实项目、尤其是反编译代码里的 AST 边界
- PHP:除了语法边界,还有真正的前端性能热点
在更早的时候,各个 front-end 的 parse 行为也没这么统一。
SLL、LL、缓存复用、错误回退这些事情,缺少一个统一抽象。很多语言前端还是各自处理自己的 parse 细节,这意味着:
- 有的地方先走 LL
- 有的地方自己做回退
- 有的地方缓存行为不一致
而这轮之后,一个很重要的基础变化就是:#4139 把 SLL-first 正式收进了统一 helper。
也就是说,现在各 front-end 默认会先尝试更快、分配更低的 SLL 路径,只有在需要时才回退到 LL,这让“先快跑、失败再兜底”变成了统一默认行为。
问题
Java 这一侧的主要问题,是:
- 真实反编译项目里会出现大量奇怪 AST 边界
- 系统经常还没走到后面的性能阶段,就先在前端 AST 这里挂住
PHP 这一侧的问题更复杂:
- 真实
pfsense项目里有一批 parser 边界问题 - 更麻烦的是 mixed HTML/PHP 大文件特别慢
真正把 PHP 这个问题拆开以后,会发现:
- 不是 SSA build 慢
- 不是
go testharness 慢 - 也不是简单的 SLL->LL fallback 导致慢
真正的热点是:
- ANTLR 在 mixed HTML/PHP 输入上发生了 decision explosion
- 尤其集中在
inlineHtmlStatement
方案
这一节的方案分两层。
第一层,是统一 parse 模式:
common/yak/antlr4util/sll_first_parse.go
这一层把:
SLL-first- fallback 到
LL - 错误监听
- cache detach
这些行为收到了统一 helper 里。
第二层,是 PHP 的专门优化:
common/yak/php/php2ssa/html_token_source.gocommon/yak/php/php2ssa/builder.go
这里引入了一个非常关键的能力:
decorateTokenSource func(antlr.TokenSource) antlr.TokenSource
它允许某个 front-end 在 lexer 和 CommonTokenStream 之间,插入一层自己的 TokenSource 装饰器。
最后真正最有效的优化,不是继续大改 grammar,而是给 PHP 加了一层 HTML token coalescing:
- 连续 HTML token 合并成更大的块
- PHP 起始边界和 XML 边界保留
Java 这一侧,这轮则主要是:
- 继续 fixup 真实项目里的 AST 边界
- 把反编译大目标 clean compile 跑通
现在的情况和重构结果
现在这条线已经形成了比较清楚的分工:
- Java:重点在于 fixup 和真实大目标跑通
- PHP:重点在于 front-end 性能热点真正被打下来
Java 这一侧,现在最重要的结果是:
- 真实反编译大目标里的 AST 错误和 panic 已经清到 0
- 前端不再是第一堵墙
PHP 这一侧,现在最重要的结果是:
- mixed HTML 这个最难看的热点已经被明确定位并压下去
运行效率对比
这一节最漂亮的一组数据,来自 PHP。
| | | | |
| — | — | — | — |
| benchmark | 优化前 | 优化后 | 提升 |
| BenchmarkFrontendPfsenseSystemInformationFixture | 15.36s/op | 6.95s/op | 54.74% |
| 分配字节 | 15.98 GB/op | 7.26 GB/op | 54.59% |
| 分配次数 | 259,896,130 | 117,823,714 | 54.67% |
本地当前主线补跑时,这个 benchmark 也还能稳定在:
7.82s/op
说明这条优化已经比较稳定地落到了主线上。
Java 这一侧,重点不在某个小 benchmark,而在真实项目能不能跑通。
最终 clean compile 的结果里:
- wall time
44:10.96 - parse
6m14s - save
27m25s
它说明的核心问题是:
- Java 前端现在已经不再是第一堵墙
- 后面的性能重心会继续往 save / persistence 方向推进
之前的情况
过去做这类性能优化,最贵的成本其实往往不是“写代码”,而是:
- 跑实验
- 看实验结果
- 验证思路是不是对
- 反复跑实验
- 换参数再跑
- 换目标再跑
- 换分支再跑
尤其是这种工作:
- 有大量参数组合
- 同一个目标要反复测
- 还要保留日志、做对比、回头看
人工来做,成本会非常高。
问题
这轮几个关键优化,本质上都不是“改一下马上就知道对不对”的问题。
例如:
- 常量池/SSA 搜索优化,需要反复在同一个大目标上看热点变化
- ANTLR cache reset,需要做多组参数 sweep
- PHP mixed HTML,需要反复跑 benchmark、pprof、对比不同方案
如果这些事情都手工做,实验成本会非常夸张。
方案
这一轮很值得单独提一句的是:
AI agent 在这里提供了大量原本很贵、很重复的实验能力。
开发者真正做的事情,是:
- 判断方向
- 看到实验结果
- 决定最终方案
而 AI agent 帮忙做的事情,是:
- 持续跑统一目标
- 跑多组参数
- 跑多个 worktree / 多个分支
- 把结果整理回来
最典型的两条线就是:
- SSA 常量池 / 搜索链实验
- ANTLR cache reset 参数 sweep
现在的情况和重构结果
这件事带来的变化,不是“AI 替开发者写完了优化”,而是:
- 很多原本太贵、太烦、太重复的实验,现在能持续做
- 多 worktree、多参数、多轮复跑的成本被明显压低了
开发者可以把更多精力放在:
- 判断根因
- 决定取舍
- 设计实验
- 决策和审核最终实现
运行效率对比
这一节没有直接对应的“代码运行时间”对比表。
但它确实改变了这轮优化的产出方式:
- 常量池优化能做多轮基线比对
- ANTLR reset 能做整轮 sweep 和复跑
- PHP mixed HTML 能把 benchmark、pprof、规则验证一起串起来
放在这一轮里,这件事最适合用一句话来概括:
“兄弟们,ai太好用了你知道吗。”
如果把这轮 IRify 性能优化 2.0 压成一句话,那就是:
这一轮不是只做了“更快”,而是把几条最关键的路径真正做成了“更快、更稳、更可继续优化”。
这一轮最值得记住的五件事是:
1、SSA 编译和相关文档更统一了,ssa.to/docs 也跟着补齐了。
2、SSA 指令搜索开始从字符串路径走向常量池 / id 路径,真正把大项目里的重复搜索问题打下来。
3、SyntaxFlow / SFVM 的判断语句运行逻辑被重构了一轮,大量值场景下过去会拖很久的旧判断路径,已经被收住了。
4、ANTLR 这一侧,缓存清理已经不是经验值,而是做过 sweep 的“甜品点”选择;PHP mixed HTML 更是拿到了非常扎实的前后对比数据。
5、AI agent 已经开始明显降低这类开发和实验的成本。
如果说第一轮做的是“把路打通”,第二轮做的就是:
- 把最重的热点打下来
- 把最糟糕的长尾收掉
- 把最关键的默认参数选稳
而接下来的第三轮、第四轮,方向其实也已经很清楚了:
- 编译期内存继续压
- 存储与落库继续压
- lazy build 路径继续推进
- 数据流分析继续细化
也就是说,这一轮不是终点,而是一个很明确的中继站。
从这里开始,IRify 已经不再只是“能跑”,而是开始真正进入“能持续变快”的阶段。
END
更新记录
Yakit v1.4.6-0327
-
MITM高级配置增加host映射优先开关
-
history流量侧边栏支持tag筛选
-
MITM的TUN劫持增加可用性检测按钮
-
优化折叠右键菜单中复制选项
-
hosts文件上传问题修复
-
下游代理输入校验优化
-
History规则数据列表优化
-
流量分析增加AI
Memfit AI v1.0.1-0327
-
上线SKILL导入功能,并支持新建编辑操作
-
上线模型检测功能,测试模型可用性
Memfit AI v1.0.1-0326
- 上线任务规划暂停和继续功能
Yaklang 1.4.6-beta5
-
优化 AI 计划执行状态、恢复取消与错误处理
-
优化 AI memory 构建、刷写与上下文传递
-
增强输出文件复检、交付快照与结果摘要传递
-
优化 AI 工具检索,增强中文场景命中
-
增强 skill/forge 导入导出、懒加载与压缩
-
修复 Go / Java / PHP SSA 编译与解析问题
-
增强混合 HTML、反编译 AST、
pfsense兼容性 -
降低硬编码凭证与弱口令相关规则误报
-
增强 Auto Decode 的 Unicode 解码能力
-
更新 WSM 测试地址、流程与 Windows 示例
-
修复 MITM 测试抖动、过滤与 host mapping
-
修复 SPA 页面上下文销毁与 redirect 边界
-
新增 HTTPFlow 全量 Tag 查询与
0.zone支持 -
完善 vulinbox 发布签名与内置插件修复
YAK官方资源
Yak 语言官方教程: https://yaklang.com/docs/intro/ Yakit 视频教程: https://space.bilibili.com/437503777 Github下载地址: https://github.com/yaklang/yakit Yakit官网下载地址: https://yaklang.com/ Yakit安装文档: https://yaklang.com/products/download_and_install Yakit使用文档: https://yaklang.com/products/intro/ 常见问题速查: https://yaklang.com/products/FAQ
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Yak Project YAK YAK《深度拆解 IRify 性能优化2.0:从能跑到稳快省的全路径重构》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论